Czy mogę znaleźć wszystkie pliki w katalogu ze zduplikowanymi nazwami plików, bez względu na wielkość liter (wielkie i / lub małe)?
17
Czy mogę znaleźć wszystkie pliki w katalogu ze zduplikowanymi nazwami plików, bez względu na wielkość liter (wielkie i / lub małe)?
Jeśli masz narzędzia GNU (lub przynajmniej zestaw, który może poradzić sobie z liniami zakończonymi zerem), inna odpowiedź ma świetną metodę:
find . -maxdepth 1 -print0 | sort -z | uniq -diz
Uwaga: dane wyjściowe będą miały łańcuchy zakończone na zero; narzędzie, którego używasz do dalszego przetwarzania, powinno być w stanie sobie z tym poradzić.
W przypadku braku narzędzi, które obsługują wiersze z zerowym zakończeniem lub jeśli chcesz mieć pewność, że Twój kod działa w środowiskach, w których takie narzędzia nie są dostępne, potrzebujesz małego skryptu:
#!/bin/sh
for f in *; do
find . -maxdepth 1 -iname ./"$f" -exec echo \; | wc -l | while read count; do
[ $count -gt 1 ] && echo $f
done
done
Co to za szaleństwo? Zobacz tę odpowiedź, aby uzyskać wyjaśnienie technik zapewniających bezpieczeństwo dla zwariowanych nazw plików.
-mindepth
?find
; Zredagowałem odpowiedź, aby uwzględnić rozwiązanie inne niż GNU.Istnieje wiele skomplikowanych odpowiedzi powyżej, wydaje się to prostsze i szybsze niż wszystkie:
Jeśli chcesz znaleźć zduplikowane nazwy plików w podkatalogach, musisz porównać tylko nazwę pliku, a nie całą ścieżkę:
Edycja: Shawn J. Goff wskazał, że to się nie powiedzie, jeśli masz nazwy plików ze znakami nowej linii. Jeśli używasz narzędzi GNU, możesz też sprawić, by działały:
Opcja
-print0
(dla find) i-z
opcja (dla sort i uniq) powoduje, że działają one na ciągach zakończonych znakiem NUL, zamiast ciągów zakończonych znakiem nowej linii. Ponieważ nazwy plików nie mogą zawierać wartości NUL, działa to dla wszystkich nazw plików.źródło
Posortuj listę nazw plików bez rozróżniania wielkości liter i wydrukuj duplikaty.
sort
ma opcję sortowania bez rozróżniania wielkości liter. Podobnie GNUuniq
, ale nie inne implementacje, a wszystko, co możesz zrobić,uniq
to wydrukować każdy element w zestawie duplikatów oprócz pierwszego napotkanego. Dzięki narzędziom GNU, zakładając, że żadna nazwa pliku nie zawiera nowej linii, istnieje łatwy sposób wydrukowania wszystkich elementów oprócz jednego w każdym zestawie duplikatów:Przenośnie, aby wydrukować wszystkie elementy w każdym zestawie duplikatów, przy założeniu, że żadna nazwa pliku nie zawiera nowego wiersza:
Jeśli potrzebujesz dostosować nazwy plików zawierające nowe wiersze, wybierz Perla lub Pythona. Należy pamiętać, że może być konieczne dostosowanie danych wyjściowych lub lepsze przetwarzanie w tym samym języku, ponieważ poniższy przykładowy kod używa znaków nowej linii do oddzielania nazw we własnych wynikach.
Oto czyste rozwiązanie Zsh. Jest to trochę szczegółowe, ponieważ nie ma wbudowanego sposobu na zachowanie zduplikowanych elementów w tablicy lub wyniku globalnym.
źródło
Bez GNU
find
:LANG=en_US ls | tr '[A-Z]' '[a-z]' | uniq -c | awk '$1 >= 2 {print $2}'
źródło
tr
bardzo prawdopodobne jest, że spowoduje spustoszenie w każdym zestawie znaków, który wykorzystuje więcej niż jeden bajt na znak. Tylko pierwsze 256 znaków UTF-8 jest bezpiecznych podczas używaniatr
. Z Wikipedii tr (Unix) .. Większość wersjitr
, w tym GNUtr
i klasyczny Unixtr
, działa na SINGLE BYTES i nie jest zgodna z Unicode ..uniq
ma flagę bez rozróżniania wielkości liter i.W końcu udało mi się to w ten sposób:
Użyłem
find
zamiastls
dlatego, że potrzebowałem pełnej ścieżki (wiele podkatalogów). Nie znalazłem, jak to zrobićls
.źródło
sort
iuniq
mają ignorować przypadków flagi, F i I odpowiednio.Dla każdego, kto chce następnie zmienić nazwę itp. Jednego z plików:
źródło