Nul*_*ptr 3 grep sed awk tail head
从“ cat line x 到 line y on a large file ”的一个小问题:
我有一个巨大的文件(2-3 GB)。我只想从具有“foo:”的行到具有“goo:”的行进行猫/打印。假设“foo:”和“goo:”在一个文件中只出现一次;"foo:" 继续 "goo:"。
到目前为止,这是我的方法:
grep -nr "foo:" bigfile123456: foo: hello world!和654321: goo: good bye!tail -n+123456 bigfile | head -n 530865我的问题是如何用表达式(例如,grep ...)有效地替换行号常量?
我可以编写一个简单的 Python 脚本,但只想使用组合命令来实现它。
sed -n '/foo/,/goo/p;/goo/q' <bigfile
Run Code Online (Sandbox Code Playgroud)
那只会打印那些行。如果你想要行号,你可以添加一个=.
sed -n '/foo/=;/goo/=;//q' <bigfile
Run Code Online (Sandbox Code Playgroud)
这q很重要,因为它q在调用时适合输入 - 否则sed将继续读取 infile 直到结束。
如果您不想打印foo/goo行,您可以改为:
使用 GNU sed:
sed -n '/foo/,/goo/!d;//!p;/goo/q
' <<\DATA
line1
foo
line3
line4
line5
goo
line7
DATA
Run Code Online (Sandbox Code Playgroud)
line3
line4
line5
Run Code Online (Sandbox Code Playgroud)
并与任何其他:
sed -n '/foo/G;/\n/,/goo/!d;//q;/\n/!p
' <<\DATA
line1
foo
line3
line4
line5
goo
line7
DATA
Run Code Online (Sandbox Code Playgroud)
line3
line4
line5
Run Code Online (Sandbox Code Playgroud)
但是,无论哪种方式,只要遇到搜索中的最后一行,它也会立即退出输入。
如果您可以放弃当前在子 shell 中使用某些内容来获取行号并允许另一个实用程序打印文件的方法,那么这可以完全轻松地完成awk:
如果你要打印的行之间 foo:和goo:而不是线本身,那么你可以使用以下(从这里原本拾起):
awk '/goo:/ { exit }; flag; /foo:/ { flag = 1 }' bigFile
Run Code Online (Sandbox Code Playgroud)
上面的exits 当它看到结束标记 ( goo:) 时,print如果 sflag为真,并在到达开始标记 ( )时设置flag为真 ( 1,实际上foo:)。
但是,如果您希望在输出中包含标记行,则该命令实际上更简单,正如@jasonwryan 所提到的:
awk '/foo:/,/goo:/' bigFile
Run Code Online (Sandbox Code Playgroud)
如果您一心只想获取行号,而不是使用相同的实用程序实际打印文件,那么您可以像这样获取开始和结束标记的行号:
awk '/foo:|goo:/ { print NR }' bigFile
Run Code Online (Sandbox Code Playgroud)