bash Grep 一行的一部分并替换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43308957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 16:00:19  来源:igfitidea点击:

Grep for part of a line and replace

bashscriptinggrep

提问by badgerbadger

New to Bash, using grep etc. and finding it confusing. Say I have a file that looks like this:

Bash 新手,使用 grep 等并发现它令人困惑。假设我有一个看起来像这样的文件:

ABC: first example [1.0] ----
ABC: second example [1.1] ----
DEF: third example [1.2] ----
DEF: fourth example [1.3] ----

How could I use grep to get all lines that start with ABC, end with the word example, and cut out everything in the line after example?

我怎样才能使用 grep 来获取所有以 ABC 开头、以单词 example 结尾的行,并在 example 之后删除该行中的所有内容?

Desired output

期望输出

ABC: first example
ABC: second example

回答by dawg

Given:

鉴于:

$ echo "$txt"
ABC: first example [1.0] ----
ABC: second example [1.1] ----
DEF: third example [1.2] ----
DEF: fourth example [1.3] ----

You can use sed:

您可以使用sed

$ echo "$txt" | sed -n 's/\(^ABC.*example\).*$//p'
ABC: first example
ABC: second example

If your content is in a file, you would do:

如果您的内容在文件中,您将执行以下操作:

$ sed -n 's/\(^ABC.*example\).*$//p' file

Explanation:

解释:

sed -n 's/\(^ABC.*example\).*$//p'
     ^                                 don't print unless p directive
        ^                              substitute 
           ^              ^            capture group -- parens need to be escaped
             ^                         ABC at start of line
                ^                      anything up to example
                           ^           everything after example to end of line
                              ^        replace entire line with capture group
                                  ^    p means print that if sub made

Or, you can use awk:

或者,您可以使用awk

$ echo "$txt" | awk 'match(
$ echo "$txt" | sed -n -E 's/(^ABC.*[[:<:]]example[[:>:]]).*$//p'
, /^ABC.* example/){print substr(
$ echo "$txt" | gawk 'match(
grep -o '^ABC.*\<example\>'
, /^ABC.*\<example\>/){print substr(
grep -Po '^ABC.*\bexample\b(?=[^[:alpha:]]*$)'
, RSTART, RLENGTH)}'
, RSTART, RLENGTH)}' ABC: first example ABC: second example


If you want to use word boundaries(so that exampleis different than examplesor nonexampleand *example is only matched as a standalone word) you can do:

如果您想使用单词边界(这样exampleexamplesnonexample不同,并且 *example 仅作为独立单词匹配),您可以执行以下操作:

% cat file.txt 
ABC: first example [1.0] ----
ABC: second example [1.1] ----
DEF: third example [1.2] ----
DEF: fourth example [1.3] ----

% grep -o '^ABC.*\<example\>' file.txt
ABC: first example
ABC: second example

% grep -Po '^ABC.*\bexample\b(?=[^[:alpha:]]*$)' file.txt
ABC: first example
ABC: second example

Or, with gawg:

或者,使用gawg

##代码##

回答by heemayl

With GNU grep:

使用 GNU grep

##代码##
  • -ogets only the matched portion

  • ^ABCmatches ABCat the start of the line

  • .*greedily matches everything upto example, \<matches zero-width word boundary before example, similarly \>matches word boundary after example

  • -o只获取匹配的部分

  • ^ABC匹配ABC行首

  • .*贪婪地匹配所有东西example\<匹配之前的零宽度词边界example,同样\>匹配之后的词边界example

Note that, this matches lines starting with ABCand has example, not necessarily last word as example. In the latter case, and if you meant to match only alphabetics (character class [:alpha:]) as word constituent characters, leverage PCRE (-P) if your grepsupports this (e.g. GNU grep) and use zero-width positive lookahead:

请注意,这匹配以ABC和开头的行example,不一定最后一个单词为example。在后一种情况下,如果您打算仅匹配字母(字符类[:alpha:])作为单词组成字符,-P如果您grep支持此(例如 GNU grep)并使用零宽度正前瞻,请利用 PCRE ( ) :

##代码##

Example:

例子:

##代码##