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

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

有没有简单的方法可以将管道输出保存到与其处理相同的文件中。例如,这就是我实际正在做的事情

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

我想知道是否有办法只用一行完成此操作(不使用 && 附加这些命令)

这不是办法,但可以得到一个想法

$ cat filename | sort | uniq > filename

答案1

您可以sponge使用更多工具包裹:

LC_ALL=C sort -u filename | sponge filename

您也不需要管道uniq,因为在排序时sort可以-u选择唯一的行。

请注意,在具有 UTF-8 语言环境的 GNU 系统上,sort -u或者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

答案2

您不需要任何额外的命令,例如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命令对您的文件名进行排序-u,并使用选项从中删除重复的行。然后使用-o选项将输出以就地方法写入同一个文件。

答案3

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

$ cat filename | sort | uniq > filename

管道或重定向的理念是,每个管道或重定向左侧和右侧的命令同时并行运行。右侧的命令处理左侧命令交给它的信息,而左侧的命令仍在运行。

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

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

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

您也可以将其保存到字符串变量中,但这仅当数据足够小,可以一次全部放入内存中时才有效。

答案4

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

ex -sc 'sort u|x' filename
  1. sort u唯一排序

  2. x写下是否做出了改变(他们确实做出了改变)并退出

相关内容