唯一排序:将输出重定向到同一文件
是否有任何简短的方法将管道输出保存到它处理的同一文件。 例如,这就是我实际在做的事情
$ 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
,因为sort
时sort
有唯一行的-u
选项。
请注意,在具有UTF-8语言环境的GNU系统上, sort -u
或sort | 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 ① ②
您不需要任何额外的命令,如cat
和uniq
,也不需要使用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
-
sort u
排序独特 -
x
写入是否已经进行了更改(他们有)并退出