Answers:
sort temp.txt -o temp.txt
sort --inplace *.txt
?那
find . -name \*.txt -exec sort {} -o {} \;
A sort
需要先查看所有输入,然后才能开始输出。出于这个原因,该sort
程序可以轻松提供就地修改文件的选项:
sort temp.txt -o temp.txt
具体来说,GNU文档sort
说:
通常,sort在打开输出文件之前会读取所有输入,因此您可以使用
sort -o F F
和这样的命令来安全地对文件进行排序cat F | sort -o F
。但是,sort
使用--merge
(-m
)可以在读取所有输入之前打开输出文件,因此之类的命令cat F | sort -m -o F - G
并不安全,因为sort可能F
在cat
读取完成之前就开始写入。
虽然BSD的文档sort
说:
如果[the]输出文件是输入文件之一,则sort在将输出排序并将其写入[the]输出文件之前将其复制到一个临时文件中。
诸如此类的命令uniq
可以在完成读取输入之前开始写入输出。这些命令通常不支持就地编辑(使它们难以支持此功能)。
通常,您可以使用一个临时文件来解决此问题,或者如果您绝对希望避免使用中间文件,则可以在写出缓冲区之前使用缓冲区存储完整的结果。例如,使用perl
:
uniq temp.txt | perl -e 'undef $/; $_ = <>; open(OUT,">temp.txt"); print OUT;'
在这里,perl部分从uniq
in变量中读取完整的输出$_
,然后用此数据覆盖原始文件。您甚至可以使用Bash使用您选择的脚本语言执行相同的操作。但是请注意,它将需要足够的内存来存储整个文件,在处理大文件时不建议这样做。
这是更通用的方法,可与uniq,sort和whatnot一起使用。
{ rm file && uniq > file; } < file
sponge
来自moreutils的另一种通用方法:cat file |frobnicate |sponge file
。
东武对海绵的评论本身就是一个答案。
要引用moreutils主页:
到目前为止,moreutils中最通用的工具可能是海绵(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
走了。
set -o pipefail
在你的脚本,错误的开始上mistyped_command my-important-file
会立即使脚本退出,执行前sponge
,从而保留重要文件。
在这里,一行:
sort temp.txt > temp.txt.sort && mv temp.txt.sort temp.txt
从技术上讲,不会复制到临时文件,并且“ mv”命令应该是即时的。
替代sponge
与更常见sed
:
sed -ni r<(command file) file
它适用于任何命令(sort
,uniq
,tac
,...),并使用了非常著名sed
的-i
选项(编辑文件就地)。
警告:请先尝试,command file
因为就地编辑文件本质上并不安全。
首先,你告诉sed
不打印(原)线(-n
选件),并与的帮助sed
的r
命令和bash
的进程替换,通过所产生的内容<(command file)
将保存在输出到位。
您可以将此解决方案包装为一个函数:
ip_cmd() { # in place command
CMD=${1:?You must specify a command}
FILE=${2:?You must specify a file}
sed -ni r<("$CMD" "$FILE") "$FILE"
}
$ cat file
d
b
c
b
a
$ ip_cmd sort file
$ cat file
a
b
b
c
d
$ ip_cmd uniq file
$ cat file
a
b
c
d
$ ip_cmd tac file
$ cat file
d
c
b
a
$ ip_cmd
bash: 1: You must specify a command
$ ip_cmd uniq
bash: 2: You must specify a file