头,尾,然后线?

头,尾,然后线?

从文件中提取由其编号给出的行的最简单方法是什么。例如,我想要 的第 666 行somefile。您将如何在终端或 shell 脚本中执行此操作?

我可以看到类似的解决方案head -n 666 somefile | tail -n 1,甚至是半正确的解决方案cat -n somefile | grep -F 666,但一定有更好、更快、更强大的解决方案。也许使用更晦涩的unix命令/实用程序?

答案1

sed(s特雷姆编辑itor) 是适合此类工作的工具:

sed -n '666p' somefile

编辑:@tachomi 的解决方案sed '666q;d' somefile在处理巨大的文本文件时更好,因为它使得sed打印图案后退出,而不读取文件的其余部分。对于所有其他文件,差异是无关紧要的。

答案2

您可以使用 sed

sed -n '666p' somefile

或者

sed '666!d' somefile

或者在大文件中

sed '666q;d' somefile 

在 bash 脚本中

#!/usr/bin/bash
line=666
sed "$line"'q;d' somefile

答案3

POSIXly(对于大文件来说可能是最快的):

tail -n +666 | head -n1

答案4

Perl 方式:

perl -ne 'print && exit if $.==666' file

我通过创建一个数字从 1 到 999999 的文件进行测试。在这个文件中,上面和awk下面的 Perl 解决方案exit是迄今为止提到的最快的解决方案:

$ perl -le 'print for 1..999999' > file

$ time perl -ne 'print && exit if $.==666' file
666

real    0m0.004s
user    0m0.000s
sys     0m0.000s

$ time awk 'NR==666 { print ; exit ; } ' file
666

real    0m0.004s
user    0m0.000s
sys     0m0.000s

$ time tail -n +666 file | head -n1
666

real    0m0.021s
user    0m0.004s
sys     0m0.000s

$ time sed -n '666p' file
666

real    0m0.125s
user    0m0.112s
sys     0m0.012s

$ time awk 'NR==666' file
666

real    0m0.161s
user    0m0.156s
sys     0m0.000s

也就是说,您最初的解决方案head -n666 file | tail -n1也非常快、非常强大并且完全可移植。为什么你认为不是?

相关内容