我需要使用bash脚本从一个巨大的文本文件中反复删除第一行。

现在我正在使用sed - I -e "1d" $FILE -但它需要大约一分钟的时间来删除。

有没有更有效的方法来实现这个目标?


当前回答

海绵util避免了对临时文件的杂耍:

tail -n +2 "$FILE" | sponge "$FILE"

其他回答

可以使用vim这样做:

vim -u NONE +'1d' +'wq!' /tmp/test.txt

这应该更快,因为vim在处理时不会读取整个文件。

因为听起来我不能加快删除,我认为一个好的方法可能是像这样批量处理文件:

While file1 not empty
  file2 = head -n1000 file1
  process file2
  sed -i -e "1000d" file1
end

这样做的缺点是,如果程序在中间被杀死(或者如果其中有一些糟糕的sql -导致“进程”部分死亡或锁定),将会有行被跳过,或者被处理两次。

(file1包含SQL代码行)

正如帕克斯所说,你可能不会比这更快。原因是几乎没有文件系统支持从文件的开头截断,所以这将是一个O(n)操作,其中n是文件的大小。不过,您可以更快地做的是用相同数量的字节(可能是空格或注释)覆盖第一行,这可能对您有用,具体取决于您正在尝试做什么(顺便说一下,这是什么?)

如果你想修改文件,你总是可以使用原始的ed,而不是它的流继承者sed:

ed "$FILE" <<<$'1d\nwq\n'

ed命令是最初的UNIX文本编辑器,当时还没有全屏终端,更不用说图形工作站了。ex编辑器,就是在vi中键入冒号提示符时所使用的编辑器,是ed的扩展版本,因此许多相同的命令都可以工作。虽然ed是用于交互的,但它也可以通过发送一串命令以批处理模式使用,这就是这个解决方案所做的。

序列<<<$'1d\nwq\n'利用了现代shell对here-strings(<<<)和ANSI引号($'…')的支持,将输入提供给由两行组成的ed命令:1d删除第一行,然后wq将文件写回磁盘,然后退出编辑会话。

使用split怎么样?

man csplit
csplit -k file 1 '{1}'