UNI*_*est 25 shell-script files
我有在大文件的开头和结尾添加行的场景。
我试过如下图所示。
对于第一行:
sed -i '1i\'"$FirstLine" $Filename
Run Code Online (Sandbox Code Playgroud)对于最后一行:
sed -i '$ a\'"$Lastline" $Filename
Run Code Online (Sandbox Code Playgroud)但是这个命令的问题在于它附加了文件的第一行并遍历整个文件。对于最后一行,它再次遍历整个文件并附加最后一行。由于它的文件非常大(14GB),这需要很长时间。
如何在只读取文件一次的情况下在文件开头添加一行,在文件末尾添加另一行?
Chr*_*own 22
sed -i
使用临时文件作为实现细节,这就是您所经历的;但是,在不覆盖现有内容的情况下将数据添加到数据流的开头需要重写文件,即使避免sed -i
.
如果重写文件不是一种选择,您可以考虑在读取文件时对其进行操作,例如:
{ echo some prepended text ; cat file ; } | command
Run Code Online (Sandbox Code Playgroud)
此外, sed 用于编辑流——文件不是流。使用专门用于此目的的程序,例如 ed 或 ex。-i
sed的选项不仅不可移植,而且还会破坏文件的任何符号链接,因为它本质上是删除它并重新创建它,这是毫无意义的。
您可以在单个命令中执行此操作,ed
如下所示:
ed -s file << 'EOF'
0a
prepend these lines
to the beginning
.
$a
append these lines
to the end
.
w
EOF
Run Code Online (Sandbox Code Playgroud)
请注意,根据您的 ed 实现,它可能会使用分页文件,这要求您至少有那么多可用空间。
请注意,如果您想避免在磁盘上分配文件的整个副本,您可以执行以下操作:
sed '
1i\
begin
$a\
end' < file 1<> file
Run Code Online (Sandbox Code Playgroud)
这使用的事实是,当它的 stdin/stdout 是一个文件时,sed
按块读取和写入。所以在这里,只要您添加的第一行小于sed
的块大小(应该是 4k 或 8k 之类的东西),它就可以覆盖它正在读取的文件。
请注意,如果由于某种原因sed
失败(被杀,机器崩溃......),你最终会处理一半的文件,这意味着一些数据在中间的某个地方丢失了第一行的大小。
另请注意,除非您sed
是 GNU sed
,否则它不适用于二进制数据(但由于您使用的-i
是 GNU sed)。