#!/bin/sh
LASTBASE=""
find $1 -type f -print | rev | sort | rev | while read FILE
do
BASE=$(basename "$FILE")
if [ "$BASE" = "$LASTBASE" ]; then
rm "$FILE"
LASTBASE="$BASE"
done
Если вы направите вывод find
в while read
цикл, вы можете разбираться с ними построчно:
find nnn/ -type f -print | rev | sort | rev | while read FILE; do
...
done
редактировать: Таким образом, этот метод не работает, если имена файлов содержат двойные (последовательные) пробелы, потому что read
фактически разделяет очередь в соответствии с $IFS
а затем снова присоединяется к нему при сохранении последней переменной. Чтобы решить эту проблему, вы можете временно изменить $IFS
чтобы отключить разбиение:
OIFS="$IFS"
IFS=""
find | while read...
IFS="$OIFS"
редактировать: test
(который совпадает с [
) не имеет ==
оператор, ты просто хочешь =
.
Я только что нашел эту «жемчужину» в старой истории bash, и она, ну, действительно работает без пробелов в именах файлов.
for hash in `find . -exec md5sum {} \; 2>/dev/null | sort | awk '{ print $1 }' | uniq -d`; do
find . -exec md5sum {} \; 2>/dev/null | grep $hash | awk '{print $2 }';
done;
неофициальный:
пример вывода:
./aFile
./aFolder/aFile
./1000digitsOfPI
./a/b/c/thousanddigitsofPI
./b File
./bFolder/cFolder/b File
Удаление здесь не реализовано, потому что может быть сложно решить, какую версию дублированных файлов вы хотите сохранить.
Если вы хотите просто смотреть на имена файлов, а не на содержимое, это станет еще проще:
for name in `find . -type f -printf "%f\n" | sort | uniq -d`; do
find . -name $name;
done;
Обновление: к сожалению, эта версия снова ломается с пробелами в именах файлов.
Проблема заключается в этой строке кода for FILE in $FILES; do
- цикл for назначает переменную FILE на основе разделителя пробелов. Поэтому, если в файле есть один или несколько пробелов, он не сработает. Просто измените IFS по умолчанию с пробела на новую строку или табуляцию. Если я правильно помню, вы можете установить IFS в bash, используя что-то вроде этого:
IFS = $ '\ n'