我是盲目的还是没有像--in-place
for这样的选择sort
?
为了将结果保存到输入文件中,sed 使用-i
( --in-place
)。
将输出重定向sort
到输入文件
sort < f > f
结果使其变空。如果没有--in-place
选择 - 也许有一些技巧可以做到这一点便利方式?
(我脑子里唯一想到的是:
sort < f > /tmp/f$$ ; cat /tmp/f$$ > f ; rm /tmp/f$$
搬家不是正确的选择,因为文件权限可能会改变。这就是为什么我用临时文件的内容覆盖然后将其删除。)
答案1
sort
具有-o
(或 --output
) 选项,该选项将文件名作为参数。程序将数据写入临时文件,然后在排序完成后覆盖原始输入文件(只有在读取所有输入数据后才会发生这种情况)。 (这与所做的本质上是一样的sed -i
。)
从GNU sort
信息页面:
-o OUTPUT-FILE
--output=OUTPUT-FILE
-
将输出写入输出文件而不是标准输出。通常,
sort
在打开之前读取所有输入输出文件sort -o F F
,因此您可以使用和等命令安全地对文件进行排序cat F | sort -o F
。然而,sort
with --merge
( -m
) 可以在读取所有输入之前打开输出文件,因此像这样的命令cat F | sort -m -o F - G
并不安全,因为可能会在读取完成之前sort
开始写入。F
cat
在较新的系统上,如果设置了,则-o
不能出现在输入文件之后 ,例如.可移植脚本应 在任何输入文件之前指定。POSIXLY_CORRECT
sort F -o F
-o OUTPUT-FILE
-o output
-
指定要使用的输出文件的名称,而不是标准输出。该文件可以与输入文件之一相同。
sort
如果磁盘空间不足或磁盘配额不足,或者sort
写入输出文件时系统崩溃,或者发生其他错误,则可能会丢弃(即销毁)部分或全部数据。
简而言之,要就地对文件进行排序,可以使用以下命令:
sort -o filename filename
答案2
您可以使用sponge
函数,首先浸泡stdin
然后将其写入文件,例如:
sort < f | sponge f
其缺点sponge
是它将输出临时存储在内存中,这对于大文件可能会出现问题。否则,您必须先将其写入文件,然后覆盖原始文件。
然而,正如其他答案所指出的那样,就地修改通常不是一个好主意,因为在进程(例如进程sponge
)的中间,机器可能会崩溃,然后您可能会丢失原始文件和新文件。您最好先将其写入另一个文件,然后使用原子mv
(移动)指令。
答案3
用输出文件覆盖输入文件是危险的,因为如果程序或系统在写入文件时崩溃,那么两者都会丢失。
一些程序(主要是 GNU 版本)具有就地选项(例如,-i
在 perl 和 GNU sed 上;-o
在 GNU sort 上)。他们的工作方式是将数据放入临时文件中,然后将其移动到位。
对于没有此选项的程序,科林·沃森的sponge
效用(包括在Joey Hess 的 moreutils)为任何程序自动完成这项工作(示例:我可以cut
就地更改文件吗?;如何使 iconv 用转换后的输出替换输入文件?)。但是,请注意,即使失败,也do_stuff | sponge myfile
始终会覆盖,可能会出现空或不正确的输出:无法检测通过管道传输到其中的命令是否成功。因此,与使用临时文件相比,输入很方便,但不安全。myfile
do_stuff
sponge
仅在极少数情况下,您无法使用相同的权限重新创建原始文件,我才建议就地覆盖该文件。在这种情况下,您最好将原始输入保存在某处。然后您可以简单地处理输入的副本并将其发送到原始文件中。
cp -p f ~/f.backup
sort <~/f.backup >|f
rm ~/f.backup # optional
答案4
使用-o
或尝试 vim 方式:
$ ex -s +'%!sort' -cxa file.txt