我是盲人还是没有像--in-place这样的sort选项?

为了将结果保存到输入文件中,sed使用-i--in-place)。 sort到输入文件

sort < f > f


将其清空。如果没有--in-place选项-也许有一些技巧可以方便地做到这一点?

(我唯一想到的是: >
移动不是正确的选择,因为文件权限可能会更改。这就是为什么我用临时文件的内容覆盖,然后将其删除。)

评论

还有一个就地功能,允许就地使用任何命令。

@sr_,这是一个有趣的命令,但是它不适用于任何命令,只有那些写入速度不比读取速度快的命令(否则,它将在命令读取之前破坏输入文件)。不能保证它可以与sort一起使用。

@cjm,我真的不确定,但是这不应该处理这种情况吗?

@sr_,我认为您是对的。我阅读了说明,而不是查看源代码。尽管对于真正的大文件,它可能会耗尽缓冲区的内存并崩溃(看起来好像它不检查malloc的NULL返回)。

@cjm:的确是这样。

#1 楼

sort具有-o, --output选项,该选项以文件名作为参数。如果与输入文件相同,则将结果写入临时文件,然后覆盖原始输入文件(与sed -i所做的完全相同)。

GNU sort信息页面:

`-o OUTPUT-FILE'
`--output=OUTPUT-FILE'
      Write output to OUTPUT-FILE instead of standard output.  Normally,
      `sort' reads all input before opening OUTPUT-FILE, so you can
      safely sort a file in place by using commands like `sort -o F F'
      and `cat F | sort -o F'.  However, `sort' with `--merge' (`-m')
      can open the output file before reading all input, so a command
      like `cat F | sort -m -o F - G' is not safe as `sort' might start
      writing `F' before `cat' is done reading it.

      On newer systems, `-o' cannot appear after an input file if
      `POSIXLY_CORRECT' is set, e.g., `sort F -o F'.  Portable scripts
      should specify `-o OUTPUT-FILE' before any input files.


,以及来自Open Group基本规范第7期:

-o  output
    Specify the name of an output file to be used instead of the standard 
    output. This file can be the same as one of the input files.


评论


没错!有用 !我在人工排序中看不到任何线索-它是未记录的功能吗?它是标准便携式产品吗?

– Grzegorz Wierzowiecki
2012年1月22日上午10:13

@GrzegorzWierzowiecki:参见更新。

– Enzotib
2012年1月22日上午10:24

好的答案:)。

– Grzegorz Wierzowiecki
2012年1月22日上午11:12

总结:sort -o <文件名> <文件名>将安全地对文件进行排序。

– phyatt
16 Mar 1 '16 at 14:52

只是一个警告:对我的文件(stackoverflow.com/questions/36292307/…)进行排序时,排序引发了错误,结果,输入文件被空输出覆盖了!

–mwfearnley
20-10-19在10:22

#2 楼

您可以使用sponge函数,该函数首先吸收stdin,然后将其写入文件,例如:

sort < f | sponge f


sponge的缺点是它将存储输出临时存储在内存中,这对于大文件可能是有问题的。否则,必须先将其写入文件,然后再覆盖原始文件。一个进程(例如sponge一个进程),计算机可能会崩溃,然后您可能会丢失原始文件和新文件。您最好先将其写入另一个文件,然后使用原子mv(移动)指令。

评论


另一个缺点:海绵不是标准的Unix工具。必须安装它。

–ron rothman
20年8月27日在1:04

#3 楼

用输出文件覆盖输入文件是很危险的,因为如果在编写文件时程序或系统崩溃,则您将同时丢失这两个文件。就地选项(例如,在perl和GNU sed上为-i;在GNU排序上为-o)。它们的工作方式是将数据放入一个临时文件中,然后将其移动到位。对于没有此类选项的程序,Colin Watson的sponge实用程序(包括在Joey Hess的moreutils中)可以安全地执行任何程序的工作(例如:我可以使cut到位更改文件吗?转换后的输出?)。

仅在极少数情况下,您无法使用相同的权限重新创建原始文件,我建议才覆盖该文件。在这种情况下,最好将原始输入保存在某个地方。然后,您可以简单地处理输入的副本并将其发送到原始文件中。

cp -p f ~/f.backup
sort <~/f.backup >|f
rm ~/f.backup # optional


评论


sort -o不是特定于GNU的,并且特别设计用于在适当的地方覆盖文件。 sort在完全读取其输入(使用内存或临时文件存储数据)之前无法开始写入其输出,因此很自然地应该能够覆盖其输入。

–StéphaneChazelas
2015年11月8日15:47

实际上,这是GNU排序不是POSIX的一种情况,因为不能保证sort -mo file1 file1 file2可以工作,而传统排序知道如何解决该问题(在70年代的Unix V7中已经存在)。

–StéphaneChazelas
2015年11月8日15:56

@JoelCross Odd,sort -o在coreutils 8.25中对我有用,并且该属性记录在手册中(请注意,只有在排序时才这样,而在合并时才这样)。如果可以重现此错误,请发送错误报告(指示确切的命令行,确切的输入文件,正在其上运行的系统以及如何获取二进制文件)。

–吉尔斯'所以-不再是邪恶的'
16年8月24日在10:07

#4 楼

使用-o或尝试vim-way:

$ ex -s +'%!sort' -cxa file.txt