Linux 输出大文件的一小段
复制本地路径 | 在线编辑
一个大文件输出其中的小部分行,在网上找到了解决方案, 发现有好几种, 记录一下自己的看法。重点在后面的理解。
参考: https://unix.stackexchange.com/questions/47407/cat-line-x-to-line-y-on-a-huge-file
解决方案
假如输出 X 到 Y 行, 有这几种方式
awk "NR >= X && NR <= Y" /path/to/file
tail -n "+$X" /path/to/file | head -n "$((Y-X+1))"
head -n "+$Y" /path/to/file | tail -n "$((X))"
sed -n -e 'X,Y p' -e 'Y q' /tmp/a
思考
上面的网站说第二种是最快的,这个让我感到很困惑,第二或者三种方法按理来说 tail 前的所有内容都会传入到 head 中,应该很浪费时间, 而第四种方法中利用了 sed 的指定特定行的特点,不应该很快吗。
解释如下:
-
找到文件的某一行没有专门的方法, 只有遍历文件通过有多少 '\n' 来实现。 以前在汇编和 C 语言中有文件指针偏移,但是那个是偏移字节数,偏移行数确实是无法立刻完成的。所以即使使用
sed中的指定行其实也是需要遍历的。 -
第二种方法中
tail会从后往前扫,除了前 X 行不会扫到;然后head从前往后扫,会扫 (Y-X) 行。假如文件一共 N 行, 那么扫过的内容为 (N-X) + (Y-X), 也就是从 X 往后的行数 加上 X 到 Y 的行数。 -
第三种方法一共是 (Y) + (Y-X), 也就是从 Y 往前的行数 加上 X 到 Y 行数
-
第四种方法中
sed就会一直往后扫, 内容是从 Y 往前的行数。
对比一下,如果 X 比较靠后了,那么第二种方法会比第四种方法要更快。如果 Y 比较靠前,那么第四种 sed 应该更快。