hee*_*ayl 8 grep text-processing
假设我有一个包含以下两行的文件:
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
2014-05-05 09:12:17 /aa/bbbb/cccccc?dddddddd 16767
Run Code Online (Sandbox Code Playgroud)
我只需要获取包含模式的行/aa/bbbb/cccccc,我不需要包含额外字符的第二行,即?dddddddd. 现在当我尝试
grep '/aa/bbbb/cccccc' file
Run Code Online (Sandbox Code Playgroud)
然后两条线都被选中。我需要完整的行,所以grep -o不可能是一个解决方案。
使用grep的可能解决方案是什么,以便根据搜索模式仅选择第一行?
ter*_*don 10
最简单的方法是在模式后添加一个空格:
$ grep '/aa/bbbb/cccccc ' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)
或者,匹配各种空格:
$ grep '/aa/bbbb/cccccc[[:space:]]' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)
或者
$ grep -P '/aa/bbbb/cccccc\s+' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)
或者,积极向前看:
$ grep -P '/aa/bbbb/cccccc(?=\s)' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)
或者,有一个负面的前瞻:
$ grep -P '/aa/bbbb/cccccc(?!\S)' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)
或者您可以反转匹配:
$ grep -v 'c?' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)
或者,也匹配只包含您的模式(没有尾随空格)的行:
grep -P '/aa/bbbb/cccccc(\s+|$)' file
grep -E '/aa/bbbb/cccccc(\s+|$)' file
Run Code Online (Sandbox Code Playgroud)
或者,您可以只使用一个小脚本:
在 awk 中:
$ awk '$3=="/aa/bbbb/cccccc"' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)
或者,如果您不知道您的模式在哪个字段中
$ awk '{for(i=1;i<=NF;i++){if($i=="/aa/bbbb/cccccc"){print}}}' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)在 Perl 中
$ perl -ane 'print if grep {$_ eq "/aa/bbbb/cccccc"} @F' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Run Code Online (Sandbox Code Playgroud)尝试使用-P(Perl-regexp)参数的以下 grep 命令。
grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
Run Code Online (Sandbox Code Playgroud)
(?<!\S)这个否定的lookbehind断言字符串前面的字符/aa/bbbb/cccccc将是任何但不是非空格字符。
(?!\S) 负前瞻断言匹配后的字符将是任何字符,但不是非空格字符。
另一个grep,
grep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
Run Code Online (Sandbox Code Playgroud)
通过蟒蛇,
script.py
#!/usr/bin/python3
import re
import sys
file = sys.argv[1]
with open(file, 'r') as f:
for line in f:
for i in line.split():
if i == "/aa/bbbb/cccccc":
print(line, end='')
Run Code Online (Sandbox Code Playgroud)
将上述代码保存在一个文件中并将其命名为script.py. 然后通过执行上面的脚本
python3 script.py /path/to/the/file/you/want/to/work/with
Run Code Online (Sandbox Code Playgroud)