我的一个文件夹中有超过 1000 个子目录。其中一些以相同的字符串开头,我想找到其名称的前 5 个字符也是另一个目录的前 5 个字符的所有目录。
我不想搜索特定的字符串,我需要一种读取第一个子目录的名称并将其与其他子目录名称的前 5 个字符进行比较的方法。然后我需要对第二个子目录等重复该过程。
找到的所有此类名称都应写入文本文件。
答案1
下面的命令将执行您想要的操作。
find . -maxdepth 1 -type d | sort | uniq -D -w 7
列出find
当前目录中的所有目录,对其进行过滤sort
(使用 的先决条件uniq
),然后使用uniq
打印所有重复项,仅使用前 7 个字符进行比较。我们使用 7 个字符而不是 5 个,因为前 2 个字符将是./
。
答案2
您可以使用参数扩展来检查字符串的前 5 个字符。
只需循环排序的目录名即可。具有相同前缀的目录在这样的列表中应该是相邻的。
$keep
包含具有不同前缀的第一个目录,$printed
是一个标志,用于防止$keep
在存在多个具有相同前缀的目录时多次打印。
#! /bin/bash
printed=0
keep=''
for dir in */ ; do
if [[ ${dir:0:5} == ${keep:0:5} ]] ; then
if ((!printed)) ; then
echo "$keep"
printed=1
fi
echo "$dir"
else
printed=0
keep=$dir
fi
done
答案3
如果您的目录名称不包含空格,您可以执行以下操作:
find . -type d -printf '%f\n' |
perl -lne '/.{1,5}/; push @{$k{$&}},$_;
END{
map{print if scalar(@{$k{$_}})>1}keys(%k)
}' > results.txt
这将找到当前目录的所有子目录并打印它们的名称(-printf '%f\n'
假设您find
支持printf
)。该perl
脚本采用每个名称的前 5 个字符,并将它们用作数组哈希的键,数组的值是目录名称。然后,打印任何多次找到的名称。
如果你的目录名可以包含换行符,你可以BEGIN{$/="\0"}
在 Perl 脚本的开头添加广告:
find . -type d -printf '%f\0' |
perl -lne 'BEGIN{$/="\0"} /.{1,5}/; push @{$k{$&}},$_;
END{
map{print if scalar(@{$k{$_}})>1}keys(%k)
}' > results.txt
答案4
感谢您的所有建议和发布的解决方案!我最终使用了find . - maxdepth 1 -type d -print0 | sort -z | uniq -zD -w 7 | tr '\0' '\n'
虽然它没有按正确的字母顺序显示输出,但“重复项”显示在相邻的位置 - 这是更重要的事情。在这里学到了很多东西(再次:-)