使用GNU sort
和printf
内置的shell (如今,除了的某些变体外,所有类似POSIX 的外壳pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
现在,存在的问题是,由于该管道的两个组件同时并独立运行,因此当左边的那个组件扩展*
glob时,右边的那个组件可能已经创建了output
文件,这可能会引起问题(也许-u
此处不存在)就像output
输入和输出文件一样,因此您可能希望将输出转到另一个目录(> ../output
例如),或者确保glob与输出文件不匹配。
在这种情况下解决它的另一种方法是编写它:
printf '%s\0' * | sort -u --files0-from=- -o output
这样一来,它的sort
开放output
写入和(在我的测试),它已收到文件前的完整列表,它不会做(这么长时间后,水珠已扩大)。output
如果所有输入文件都不可读,这也将避免破坏。
用zsh
或编写的另一种方式bash
sort -u --files0-from=<(printf '%s\0' *) -o output
这是使用进程替换(其中的<(...)
位置由指向管道读取端的文件路径替换printf
)。该功能来自ksh
,但ksh
坚持在<(...)
命令中扩展单独的参数,因此您不能在--option=<(...)
语法中使用它。它将使用以下语法运行:
sort -u --files0-from <(printf '%s\0' *) -o output
请注意,cat
在某些文件不以换行符结尾的情况下,您会看到与提供文件输出的方法有所不同:
$ printf a > a
$ printf b > b
$ printf '%s\0' a b | sort -u --files0-from=-
a
b
$ printf '%s\0' a b | xargs -r0 cat | sort -u
ab
另请注意,该代码sort
使用语言环境(strcollate()
)中的归类算法进行排序,并sort -u
报告按该算法对同一行进行排序的每一行,而不是字节级别的唯一行。如果您只关心行在字节级别上是唯一的,而不是太在乎它们的排序顺序,则您可能需要将语言环境固定为C,其中基于字节值进行排序(memcmp()
;可能会加快速度)事情显着上升):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sort
会自动为多个文件输入..但随后sort -u *
也会失败,Argument list too long
我想