唯一排序:将输出重定向到同一文件

是否有任何简短的方法将管道输出保存到它处理的同一文件。 例如,这就是我实际在做的事情

$ cat filename | sort | uniq > result $ rm -f filename $ mv result filename 

我想知道是否有办法在一行中完成它(不使用&&附加这些命令)

这不是方法,而是要有所了解

 $ cat filename | sort | uniq > filename 

你可以使用moreutils包中的sponge

 LC_ALL=C sort -u filename | sponge filename 

您也不需要管道到uniq ,因为sortsort有唯一行的-u选项。

请注意,在具有UTF-8语言环境的GNU系统上, sort -usort | uniq sort | uniq没有给你独特的行,但是第一行来自当前语言环境中排序相同的行序列。

 $ printf '%b\n' '\U2460' '\U2461' | LC_ALL=en_US.utf8 sort | LC_ALL=en_US.utf8 uniq ① 

只给了你 。 将语言环境更改为C会强制基于字节值的排序顺序:

 $ export LC_ALL=C $ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C sort | LC_ALL=C uniq ① ② 

您不需要任何额外的命令,如catuniq ,也不需要使用rm命令和mv命令来删除和重命名文件名。 只需使用简单的命令。

 sort -u filename -o filename 

  -u, --unique with -c, check for strict ordering; without -c, output only the first of an equal run -o, --output=FILE write result to FILE instead of standard output 

它是如何工作的?

sort命令对文件名进行sort并使用-u选项从中删除重复的行。 然后使用-o选项使用in place方法将输出写入同一文件。

您建议的示例(如下所示)不起作用,因为您实际上是在同时读取和写入同一文件。

 $ cat filename | sort | uniq > filename 

使用管道或重定向的想法是每个管道的左侧和右侧的命令或重定向同时并行运行。 右边的命令处理从左边的命令切换到它的信息,而左边的命令仍然在运行。

为了使您的方案工作,从文件读取的命令需要在写入文件的命令开始之前完成。 为了使其工作,您需要首先将输出重定向到临时位置,然后一旦完成,将其从临时位置发送回文件。

更好的方法是在前面的例子中,你重定向到一个临时文件,然后将该文件重命名为原始文件(除了你不需要先删除文件,因为移动删除任何现有的目标) 。

 $ cat filename | sort | uniq > result $ mv -f result filename 

您也可以将其保存到字符串变量中,除非只有在数据足够小以便一次完全适合内存时才有效。

您可以使用tee命令:

 sort -u filename | tee filename > /dev/null 

tee命令从标准输入读取并写入标准输出文件。

您可以在Ex模式下使用Vim:

 ex -sc 'sort u|x' filename 
  1. sort u排序独特

  2. x写入是否已经进行了更改(他们有)并退出