Linux 如何在模式后搜索内容?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10358547/
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-08-06 06:02:51  来源:igfitidea点击:

How to grep for contents after pattern?

linuxgrep

提问by Lexicon

Given a file, for example:

给定一个文件,例如:

potato: 1234
apple: 5678
potato: 5432
grape: 4567
banana: 5432
sushi: 56789

I'd like to grep for all lines that start with potato:but only pipe the numbers that follow potato:. So in the above example, the output would be:

我想对所有以 开头的行进行 grep,potato:但只传递后面的数字potato:。所以在上面的例子中,输出将是:

1234
5432

How can I do that?

我怎样才能做到这一点?

采纳答案by rid

grep 'potato:' file.txt | sed 's/^.*: //'

greplooks for any line that contains the string potato:, then, for each of these lines, sedreplaces (s///- substitute) any character (.*) from the beginning of the line (^) until the last occurrence of the sequence :(colon followed by space) with the empty string (s/...//- substitute the first part with the second part, which is empty).

grep查找包含该字符串的任何行potato:,然后,对于这些行中的每一行,从该行 ( )的开头直到最后一次出现该序列(冒号后跟空格)的任何字符 ( )sed替换(s///- 替换)为空字符串(- 用第二部分替换第一部分,第二部分是空的)。.*^:s/...//

or

或者

grep 'potato:' file.txt | cut -d\   -f2

For each line that contains potato:, cutwill split the line into multiple fields delimited by space (-d\- d= delimiter, \= escaped space character, something like -d" "would have also worked) and print the second field of each such line (-f2).

对于包含 的每一行potato:cut将把该行分成多个由空格分隔的字段(-d\- d= 分隔符,\= 转义空格字符,类似的东西-d" "也可以工作)并打印每个这样的行的第二个字段 ( -f2)。

or

或者

grep 'potato:' file.txt | awk '{print }'

For each line that contains potato:, awkwill print the second field (print $2) which is delimited by default by spaces.

对于包含 的每一行potato:awk将打印print $2默认情况下由空格分隔的第二个字段 ( )。

or

或者

grep 'potato:' file.txt | perl -e 'for(<>){s/^.*: //;print}'

All lines that contain potato:are sent to an inline (-e) Perlscript that takes all lines from stdin, then, for each of these lines, does the same substitution as in the first example above, then prints it.

包含的所有行都potato:被发送到一个内联 ( -e) Perl脚本,该脚本从 中提取所有行stdin,然后对这些行中的每一行进行与上面第一个示例中相同的替换,然后将其打印出来。

or

或者

awk '{if(/potato:/) print }' < file.txt

The file is sent via stdin(< file.txtsends the contents of the file via stdinto the command on the left) to an awkscript that, for each line that contains potato:(if(/potato:/)returns true if the regular expression /potato:/matches the current line), prints the second field, as described above.

文件通过stdin< file.txt将文件的内容发送stdin到左侧的命令)发送到一个awk脚本,该脚本对于包含potato:if(/potato:/)如果正则表达式/potato:/与当前行匹配则返回true)的每一行,打印第二个字段,如所述以上。

or

或者

perl -e 'for(<>){/potato:/ && s/^.*: // && print}' < file.txt

The file is sent via stdin(< file.txt, see above) to a Perl script that works similarly to the one above, but this time it also makes sure each line contains the string potato:(/potato:/is a regular expression that matches if the current line contains potato:, and, if it does (&&), then proceeds to apply the regular expression described above and prints the result).

该文件通过stdin( < file.txt,见上文) 发送到一个 Perl 脚本,该脚本的工作方式与上面的类似,但这次它还确保每一行都包含字符串potato:(/potato:/是一个正则表达式,如果当前行包含potato:,并且,如果它执行 ( &&),然后继续应用上述正则表达式并打印结果)。

回答by thb

sed -n 's/^potato:[[:space:]]*//p' file.txt

One can think of Grep as a restricted Sed, or of Sed as a generalized Grep. In this case, Sed is one good, lightweight tool that does what you want -- though, of course, there exist several other reasonable ways to do it, too.

人们可以将 Grep 视为受限制的 Sed,或者将 Sed 视为广义的 Grep。在这种情况下,Sed 是一款出色的轻量级工具,可以满足您的需求——当然,还有其他几种合理的方法可以做到这一点。

回答by mohit6up

Or use regex assertions: grep -oP '(?<=potato: ).*' file.txt

或者使用正则表达式断言: grep -oP '(?<=potato: ).*' file.txt

回答by Chris Koknat

This will print everything after each match, on that same line only:

这将在每次匹配后打印所有内容,仅在同一行上:

perl -lne 'print  if /^potato:\s*(.*)/' file.txt

This will do the same, except it will also print all subsequent lines:

这将执行相同的操作,除了它还会打印所有后续行:

perl -lne 'if ($found){print} elsif (/^potato:\s*(.*)/){print ; $found++}' file.txt

These command-line options are used:

使用这些命令行选项:

  • -nloop around each line of the input file
  • -lremoves newlines before processing, and adds them back in afterwards
  • -eexecute the perl code
  • -n循环输入文件的每一行
  • -l在处理之前删除换行符,然后将它们添加回
  • -e执行perl代码

回答by mightypile

You can use grep, as the other answers state. But you don't need grep, awk, sed, perl, cut, or any external tool. You can do it with pure bash.

您可以使用 grep,正如其他答案所述。但是您不需要 grep、awk、sed、perl、cut 或任何外部工具。你可以用纯 bash 来完成。

Try this (semicolons are there to allow you to put it all on one line):

试试这个(分号是为了让你把它全部放在一行上):

$ while read line;
  do
    if [[ "${line%%:\ *}" == "potato" ]];
    then
      echo ${line##*:\ };
    fi;
  done< file.txt

## tells bash to delete the longest match of ": " in $line from the front.

## 告诉 bash 从前面删除 $line 中最长的 ":" 匹配项。

$ while read line; do echo ${line##*:\ }; done< file.txt
1234
5678
5432
4567
5432
56789

or if you wanted the key rather than the value, %% tells bash to delete the longest match of ": " in $line from the end.

或者,如果您想要键而不是值, %% 会告诉 bash 从末尾删除 $line 中最长的“:”匹配项。

$ while read line; do echo ${line%%:\ *}; done< file.txt
potato
apple
potato
grape
banana
sushi

The substring to split on is ":\ " because the space character must be escaped with the backslash.

要拆分的子字符串是“:\”,因为空格字符必须用反斜杠转义。

You can find more like these at the linux documentation project.

您可以在linux 文档项目中找到更多类似的内容