我正在尝试一个天真的:
$ cat * | sort -u > /tmp/bla.txt
Run Code Online (Sandbox Code Playgroud)
失败了:
-bash: /bin/cat: Argument list too long
Run Code Online (Sandbox Code Playgroud)
因此,为了避免像(创建一个巨大的临时文件)这样的愚蠢解决方案:
$ find . -type f -exec cat {} >> /tmp/unsorted.txt \;
$ cat /tmp/unsorted.txt | sort -u > /tmp/bla.txt
Run Code Online (Sandbox Code Playgroud)
我虽然我可以使用一个一个地处理文件(这应该减少内存消耗,并且更接近流式机制):
$ cat proc.sh
#!/bin/sh
old=/tmp/old.txt
tmp=/tmp/tmp.txt
cat $old "$1" | sort -u > $tmp
mv $tmp $old
Run Code Online (Sandbox Code Playgroud)
接着是:
$ touch /tmp/old.txt
$ find . -type f -exec /tmp/proc.sh {} \;
Run Code Online (Sandbox Code Playgroud)
是否有更简单的更 unix 风格的替代:cat * | sort -u
当文件数量达到时MAX_ARG
?为这样一个常见的任务编写一个小的 shell 脚本感觉很尴尬。
ilk*_*chu 11
一个简单的修复,至少在 Bash 中有效,因为它printf
是内置的,并且命令行参数限制不适用于它:
printf "%s\0" * | xargs -0 cat | sort -u > /tmp/bla.txt
Run Code Online (Sandbox Code Playgroud)
(echo * | xargs
也可以工作,除了处理带有空格的文件名等)
find . -maxdepth 1 -type f ! -name ".*" -exec cat {} + | sort -u -o /path/to/sorted.txt
Run Code Online (Sandbox Code Playgroud)
这将连接当前目录中所有非隐藏的常规文件,并将它们的组合内容(同时删除重复行)排序到文件中/path/to/sorted.txt
。
使用 GNUsort
和一个printf
内置的 shell (现在所有类似 POSIX 的,除了 的一些变体pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
Run Code Online (Sandbox Code Playgroud)
现在,一个问题是,因为该管道的两个组件同时独立运行,当左边的一个扩展*
全局时,右边的可能已经创建了output
可能导致问题的文件(可能不是-u
这里)就像output
输入和输出文件一样,因此您可能希望将输出转到另一个目录(> ../output
例如),或者确保 glob 与输出文件不匹配。
在这种情况下解决它的另一种方法是编写它:
printf '%s\0' * | sort -u --files0-from=- -o output
Run Code Online (Sandbox Code Playgroud)
这样一来,它的sort
开放output
写入和(在我的测试),它已收到文件前的完整列表,它不会做(这么长时间后,水珠已扩大)。output
如果没有任何输入文件可读,它也将避免破坏。
另一种写法zsh
或bash
sort -u --files0-from=<(printf '%s\0' *) -o output
Run Code Online (Sandbox Code Playgroud)
那是使用进程替换(其中<(...)
被替换为引用管道读取端的文件路径printf
正在写入)。该功能来自ksh
,但ksh
坚持<(...)
将单独的参数扩展到命令中,因此您不能将其与--option=<(...)
语法一起使用。不过,它可以使用以下语法:
sort -u --files0-from <(printf '%s\0' *) -o output
Run Code Online (Sandbox Code Playgroud)
请注意,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
Run Code Online (Sandbox Code Playgroud)
另请注意,sort
在语言环境 ( strcollate()
) 中使用整理算法进行排序,并sort -u
报告按该算法排序的每组行中的一个,而不是字节级别的唯一行。如果您只关心行在字节级别是唯一的,而不太关心它们的排序顺序,您可能希望将语言环境修复为 C,其中排序基于字节值(memcmp()
;这可能会加快事情显着):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4086 次 |
最近记录: |