那可能只是:
find . -type f -size +1c -exec sort -uo {} {} ';'
Run Code Online (Sandbox Code Playgroud)
(此处跳过小于 2 字节大的文件,因为您需要至少 3 个字节来创建两个不同的行,或者可能需要 2 个字节,"\nx"
其中一个空行后跟一个未定界的行¹)。
注意默认的排序顺序sort
是基于语言环境的整理算法。
两行可以排序相同,即使它们不是逐字节相同的,尤其是当这些行包含不构成有效字符的字节序列时,以及在 Debian 等 GNU 系统上排序顺序不相同的字符时定义。
你可以做:
LC_ALL=C find . -type f -exec sort -uo {} {} ';'
Run Code Online (Sandbox Code Playgroud)
相反,在基于 ASCII 的系统(例如所有架构和内核上的 Debian)上,它将按字节值而不是语言环境整理顺序(或 IOW,C 语言环境的整理顺序基于字节值)对行进行排序,并且应该保证两个字节到字节不同的行排序不一样。
这对sort
每个文件运行一次调用。如果文件相当短,要加快速度,您可以改为zsh
:
zmodload zsh/mapfile
for f (**/*(N.)) print -rC1 -v 'mapfile[$f]' - ${(fou)mapfile[$file]}
Run Code Online (Sandbox Code Playgroud)
这避免了sort
多次运行外部命令,而是使用其o
和u
参数扩展标志来对行进行排序和唯一化。请注意,它会删除输入中的空行(如果有),并跳过隐藏文件(如果需要,请添加D
glob 限定符)。
与 GNU 相反sort -u
,zsh
不会将两个字节到字节不同的字符串视为重复(即使它们的排序相同),因此您无需将语言环境固定为 C 那里。
$ 语言环境标题charmap 英国的英语语言环境 UTF-8 $ a=( ) $ 打印 -rC1 - $a | 排序 -u (哎呀,吸血鬼消失了,因为它和仙女一样排序) $ 打印 -rC1 - ${(ou)a}
至于您关于 的问题uniq -u
,这就是它的用途,uniq -u
报告输入中唯一的行。要删除重复项,只需sort | uniq
. 的补充uniq -u
将是uniq -D
(报告所有重复的行)。
GNUuniq
过去常常报告排序相同的行序列中的第一个(因此sort -u
将与 相同sort | uniq
)。较新的版本报告相同行的第一个序列,因此sort | uniq
如果可以有不同的行排序相同,则不能再使用。
在这里,使用较新的 GNU 版本:
$ print -rC1 | sort | uniq
Run Code Online (Sandbox Code Playgroud)
由于精灵和吸血鬼在我的语言环境中排序相同,因此sort
结果将与输入中的一样(因为 GNUsort
使用稳定的排序算法),并且uniq
仅当输入发生在原始包含相邻重复项时才会删除重复项。
我们可以做的是首先sort
按字节值,然后在调用之前按整理顺序uniq
:
LC_ALL=C sort | sort | LC_ALL=C uniq
Run Code Online (Sandbox Code Playgroud)
调用uniq
underLC_ALL=C
将使旧版本和新版本的工作方式相同。
sort
如果输入中缺少该换行符,则会添加回该换行符,实际上是从该非文本文件中生成文本文件。通过跳过包含非换行字节的 1 字节大小的文件,这意味着这些文件不是固定的,因此如果您仍然想要该文本文件修复的好处,您可能希望跳过该优化,或者将优化扩展到-size +2c
if你知道你所有的文件都是格式正确的文本文件。