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
Grep for part of a line and replace
提问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:
如果您想使用单词边界(这样example与examples或nonexample不同,并且 *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
:
-o
gets only the matched portion^ABC
matchesABC
at the start of the line.*
greedily matches everything uptoexample
,\<
matches zero-width word boundary beforeexample
, similarly\>
matches word boundary afterexample
-o
只获取匹配的部分^ABC
匹配ABC
行首.*
贪婪地匹配所有东西example
,\<
匹配之前的零宽度词边界example
,同样\>
匹配之后的词边界example
Note that, this matches lines starting with ABC
and 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 grep
supports this (e.g. GNU grep
) and use zero-width positive lookahead:
请注意,这匹配以ABC
和开头的行example
,不一定最后一个单词为example
。在后一种情况下,如果您打算仅匹配字母(字符类[:alpha:]
)作为单词组成字符,-P
如果您grep
支持此(例如 GNU grep
)并使用零宽度正前瞻,请利用 PCRE ( ) :
Example:
例子:
##代码##