Попробуйте:
ls -1 | tr '[A-Z]' '[a-z]' | sort | uniq -c | grep -v " 1 "
Просто, правда :-) Разве трубопроводы не прекрасные звери?
ls -1
дает вам файлы по одному на строку, tr '[A-Z]' '[a-z]'
преобразует все заглавные буквы в строчные, sort
сортирует их (как ни удивительно), uniq -c
удаляет последующие вхождения повторяющихся строк, давая вам счет и, наконец, grep -v " 1 "
убирает те строки, где счет был один.
Когда я запускаю это в каталоге с одним «дубликатом» (я скопировал qq
в qQ
), я получаю:
2 qq
Для версии «этот каталог и каждый подкаталог» просто замените ls -1
на find .
или find DIRNAME
, если вы хотите указать определенную начальную точку каталога (DIRNAME
- это имя каталога, которое вы хотите использовать).
Это возвращает (для меня):
2 ./.gconf/system/gstreamer/0.10/audio/profiles/mp3
2 ./.gconf/system/gstreamer/0.10/audio/profiles/mp3/%gconf.xml
2 ./.gnome2/accels/blackjack
2 ./qq
которые вызваны:
pax> ls -1d .gnome2/accels/[bB]* .gconf/system/gstreamer/0.10/audio/profiles/[mM]* [qQ]?
.gconf/system/gstreamer/0.10/audio/profiles/mp3
.gconf/system/gstreamer/0.10/audio/profiles/MP3
.gnome2/accels/blackjack
.gnome2/accels/Blackjack
qq
qQ
Обновление:
На самом деле, при дальнейшем отражении tr
будет в нижнем регистре всех компонентов пути, так что оба из
/a/b/c
/a/B/c
будут считаться дубликатами , даже если они находятся в разных каталогах .
Если вы хотите, чтобы дубликаты только в одном каталоге отображались как совпадающие, вы можете использовать (довольно чудовищно):
perl -ne '
chomp;
@flds = split (/\//);
$lstf = $f[-1];
$lstf =~ tr/A-Z/a-z/;
for ($i =0; $i ne $#flds; $i++) {
print "$f[$i]/";
};
print "$x\n";'
вместо:
tr '[A-Z]' '[a-z]'
То, что он делает, это только строчные буквы последней части пути, а не все это. Кроме того, если вам нужны только обычные файлы (без каталогов, FIFO и т. Д.), Используйте find -type f
, чтобы ограничить возвращаемое.