Answers:
sed -i
使用临时文件作为实现细节,这就是您正在经历的;但是,在不覆盖现有内容的情况下将数据放在数据流的开头需要重写文件,即使避免了,也无法解决sed -i
。
如果无法重写文件,则可以在读取文件时考虑对其进行处理,例如:
{ echo some prepended text ; cat file ; } | command
此外,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
请注意,根据ed的实现,它可能会使用分页文件,要求您至少有那么多可用空间。
for
循环:for file in Tes*; do [command]; done
"$file"
,而不是Tes*
的参数ed
。
请注意,如果要避免在磁盘上分配文件的整个副本,可以执行以下操作:
sed '
1i\
begin
$a\
end' < file 1<> file
这利用了以下事实:当其stdin / stdout是文件时,sed
将按块进行读取和写入。因此,只要您添加的第一行小于sed
的块大小(应为4k或8k之类),就可以覆盖正在读取的文件。
请注意,尽管如果由于某种原因sed
失败(被杀死,机器崩溃……),您将最终处理一半的文件,这意味着某些数据的中间部分缺少第一行的大小。
还要注意,除非您sed
是GNU sed
,否则它将不适用于二进制数据(但是由于您使用-i
,因此您正在使用GNU sed)。
以下是一些选择(所有选择都会创建文件的新副本,因此请确保您有足够的空间用于该文件):
简单的回声/猫
echo "first" > new_file; cat $File >> new_file; \
echo "last" >> new_file;
awk / gawk等
gawk 'BEGIN{print "first\n"}{print}END{print "last\n"}' $File > NewFile
awk
并逐行读取文件。该BEGIN{}
块在第一行之前执行,而END{}
块在最后一行之后执行。因此,以上命令表示print "first" at the beginning, then print every line in the file and print "last" at the end
。
佩尔
perl -ne 'BEGIN{print "first\n"} print;END{print "last\n"}' $File > NewFile
这与上面用Perl编写的gawk本质上是相同的。
sed -i
它来创建临时文件。
您可以在Ex模式下使用Vim:
ex -sc '1i|ALFA' -c '$a|BRAVO' -cx file
1
选择第一行
i
插入文字和换行符
$
选择最后一行
a
附加文字和换行符
x
保存并关闭
无法在文件的开头¹插入数据,您所能做的就是创建一个新文件,写入其他数据并附加旧数据。因此,您必须至少重写一次整个文件才能插入第一行。但是,您可以追加最后一行而不重写文件。
sed -i '1i\'"$FirstLine" $Filename
echo "$LastLine" >>$Filename
或者,您可以在一次sed中组合两个命令。
sed -i -e '1i\'"$FirstLine" -e '$ a\'"$Lastline" $Filename
sed -i
创建一个新的输出文件,然后将其移到旧文件上。这意味着,在sed工作时,存在占用空间的文件的第二个副本。您可以通过在适当的位置覆盖文件来避免这种情况,但是有一些主要限制:要添加的行必须小于sed的缓冲区,并且如果系统崩溃,最终将导致文件损坏并且文件中的某些内容丢失中间,因此强烈建议您反对。
¹Linux 确实可以将数据插入文件,但是它只能插入整数个文件系统块,不能插入任意长度的字符串。它对某些应用程序(例如数据库和虚拟机)很有用,但对文本文件却没有用。
fallocate()
上的FALLOC_FL_INSERT_RANGE
可用信息man7.org/linux/man-pages/man2/fallocate.2.html
$ (echo "Some Text" ; cat file1) > file2
现代Linux内核(高于4.1或4.2)支持通过ext4和xfs文件系统上的fallocate()
系统调用FALLOC_FL_INSERT_RANGE
在文件的开头插入数据。从本质上讲,这是一个逻辑移位操作:数据在逻辑上以较高的偏移量重定位。
关于要在文件开头插入的范围的粒度存在限制。但是对于文本文件,您可能可以分配比要求更多的空间(直到粒度边界)并用空格或回车符填充,但这取决于您的应用程序
我不知道有任何可操纵文件范围的现成的Linux实用程序,但编写起来并不难:获取文件描述符并fallocate()
使用适当的参数进行调用。有关更多详细信息,请参见fallocate
系统调用的手册页:http : //man7.org/linux/man-pages/man2/fallocate.2.html
fallocate
实用程序。问题是整个块的粒度使大多数文本文件无法使用。另一个问题是范围分配和后续修改不是原子的。因此,这实际上并不能解决问题。
fallocate
原子性被破坏的位置,我很好奇)