使用sed对大文件进行有效的就地头文件删除?

Che*_*eng 25 sed text-processing

以下命令可能需要几分钟,具体取决于文件大小。有没有更有效的方法?

sed -i 1d large_file 
Run Code Online (Sandbox Code Playgroud)

man*_*ork 37

试试吧ed:

ed <<< $'1d\nwq' large_file
Run Code Online (Sandbox Code Playgroud)

如果那个“大”意味着大约 1000 万行或更多,最好使用tail. 无法进行就地编辑,但它的性能使其缺乏可以原谅:

tail -n +2 large_file > large_file.new
Run Code Online (Sandbox Code Playgroud)

编辑以显示一些时差:

(awk由 Jaypal 添加的代码在同一台机器(CPU 2.2GHz)上具有执行时间。)

bash-4.2$ seq 1000000 > bigfile.txt # further file creations skipped

bash-4.2$ time sed -i 1d bigfile.txt
time 0m4.318s

bash-4.2$ time ed -s <<< $'1d\nwq' bigfile.txt
time 0m0.533s

bash-4.2$ time perl -pi -e 'undef$_ if$.==1' bigfile.txt
time 0m0.626s

bash-4.2$ time { tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt; }
time 0m0.034s

bash-4.2$ time { awk 'NR>1 {print}' bigfile.txt > newfile.txt && mv -f newfile.txt bigfile.txt; }
time 0m0.328s
Run Code Online (Sandbox Code Playgroud)


Mat*_*Mat 6

没有办法从文件的开头有效地删除内容。从头开始删除数据需要重写整个文件。

不过,从文件末尾截断可能非常快(操作系统只需调整文件大小信息,可能会清除现在未使用的块)。当您尝试从文件头中删除时,这通常是不可能的。

如果您完全删除整个块/范围,理论上它可能是“快速的”,但是没有系统调用,因此您必须依赖文件系统特定的语义(如果存在)。(或者在第一个块/范围内有某种形式的偏移量来标记文件的真正开始,我猜。也从未听说过。)

  • 我很惊讶您的结果差异如此之大,并且可以在此处以该文件大小重现它。但是,随着文件大小的增加,好处似乎会减少(尝试使用 seq 10M,sed 为 15s,ed 为 5s)。无论如何都是好提示(+1)。 (2认同)