我想从文件中的一行“测试”单词之后的单词。意思是在实际上,我不希望在“测试”字之前出现这些词。
那个模式......
例如:
输入:
***This is a*** test page.
***My*** test work of test is complete.
输出:
test page.
work of test is complete.
答案 0 :(得分:10)
使用sed:
sed -n 's/^.*test/test/p' input
如果您想要打印不匹配的行,请不要触摸:
sed 's/^.*test/test/' input
上面的一个将删除(贪婪)所有文本,直到最后一行test
。如果你想删除第一个测试,请使用potong的建议:
sed -n 's/test/&\n/;s/.*\n//p' input
答案 1 :(得分:5)
纯bash单行:
while read x; do [[ $x =~ test.* ]] && echo ${BASH_REMATCH[0]}; done <infile
输入:infile
This is a test page.
My test work of test is complete.
输出:
test page.
test work of test is complete.
它读取文件infile
中的所有行,检查该行是否包含字符串test
,然后打印该行的其余部分(包括test
)。
sed中的相同内容:
sed's /。(测试。)/ \ 1 /'infile (哎呀!这是错误的!.*
贪婪,所以切从第二个例子线太多了)。这很有效:
sed -e 's/\(test.*\)/\x03&/' -e 's/.*\x03//' infile
我做了一些速度测试(对于原始(错误的)sed版本)。结果是,对于小文件,bash解决方案表现更好。对于较大的文件sed更好。我也尝试了这个awk版本,这对于大文件来说更好:
awk 'match($0,"test.*"){print substr($0,RSTART)}' infile
类似于perl:
perl -ne 's/(.*?)(test.*)/$2/ and print' infile
我使用了两行示例输入文件,每次都复制它。每个版本运行1000次。结果是:
Size | bash | sed | awk | perl
[B] | [sec] | [sec] | [sec] | [sec]
------------------------------------------
55 | 0.420 | 10.510 | 10.900 | 17.911
110 | 0.460 | 10.491 | 10.761 | 17.901
220 | 0.800 | 10.451 | 10.730 | 17.901
440 | 1.780 | 10.511 | 10.741 | 17.871
880 | 4.030 | 10.671 | 10.771 | 17.951
1760 | 8.600 | 10.901 | 10.840 | 18.011
3520 | 17.691 | 11.460 | 10.991 | 18.181
7040 | 36.042 | 12.401 | 11.300 | 18.491
14080 | 72.355 | 14.461 | 11.861 | 19.161
28160 |145.950 | 18.621 | 12.981 | 20.451
56320 | | | 15.132 | 23.022
112640 | | | 19.763 | 28.402
225280 | | | 29.113 | 39.203
450560 | | | 47.634 | 60.652
901120 | | | 85.047 |103.997