我有一个文件temp.txt,我想用sort
bash中的命令排序.
我希望排序的结果替换原始文件.
这不起作用(我得到一个空文件):
sortx temp.txt > temp.txt
这可以在一行中完成而无需复制到临时文件吗?
编辑:这个-o
选项非常酷sort
.我sort
在我的问题中用作例子.我遇到了与其他命令相同的问题:
uniq temp.txt > temp.txt.
有更好的通用解决方案吗?
sort temp.txt -o temp.txt
A sort
需要在开始输出之前查看所有输入.因此,sort
程序可以轻松提供一个就地修改文件的选项:
sort temp.txt -o temp.txt
具体来说,GNUsort
的文档说:
通常,sort在打开输出文件之前读取所有输入,因此您可以使用
sort -o F F
和等命令安全地对文件进行排序cat F | sort -o F
.但是,sort
with--merge
(-m
)可以在读取所有输入之前打开输出文件,因此类似命令cat F | sort -m -o F - G
不安全,因为sortF
在cat
读取之前可能会开始写入.
虽然BSD的文档sort
说:
如果[the]输出文件是输入文件之一,则在排序并将输出写入[output]文件之前,将其复制到临时文件.
诸如的命令uniq
可以在完成读取输入之前开始写入输出.这些命令通常不支持就地编辑(并且它们更难以支持此功能).
您通常使用临时文件解决此问题,或者如果您绝对想避免使用中间文件,则可以在写出之前使用缓冲区存储完整的结果.例如,用perl
:
uniq temp.txt | perl -e 'undef $/; $_ = <>; open(OUT,">temp.txt"); print OUT;'
这里,perl部分从uniq
变量中读取完整输出$_
,然后用这些数据覆盖原始文件.您可以使用您选择的脚本语言执行相同的操作,甚至可以使用Bash.但请注意,它需要足够的内存来存储整个文件,这在处理大文件时是不可取的.
这是一种更通用的方法,适用于uniq,sort和whatnot.
{ rm file && uniq > file; } < file
东武对海绵的评论保证本身就是一个答案.
引用moreutils主页:
到目前为止,moreutils中最常用的工具可能是sponge(1),它允许你做这样的事情:
% sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd
但是,Steve Jessop在这里发表sponge
了同样的问题.如果管道中的任何命令在sponge
失败之前,则原始文件将被写入.
$ mistyped_command my-important-file | sponge my-important-file mistyped-command: command not found
哦,哦,my-important-file
走了.
你去,一行:
sort temp.txt > temp.txt.sort && mv temp.txt.sort temp.txt
从技术上讲,没有复制到临时文件,'mv'命令应该是即时的.