Мне нужно удалить файлы с одинаковым размером, но не идентичным содержимым в Linux, поэтому fdupes не является вариантом.
Я попробовал следующую команду, однако она не удалила все файлы одинакового размера (не знаю почему)
last=-1; find . -type f -name '*.png' -printf '%f\0' | sort -nz | while read -d '' i; do s=$(stat -c '%s' "$i"); [[ $s = $last ]] && rm "$i"; last=$s; done
Есть идеи? Что я сделал не так?
EDIT: Я допустил ошибку в первом сообщении. Мне нужнодержатьодин файл указанного размера, например:
1.png # 23,5 Kb
2.png # 24,6 Kb
4.png # 24,6 Kb > remove
8.png # 24,6 Kb > remove
16.png # 23,5 Kb
По сути, я хочу удалить дубликаты, но не только по контрольной сумме, а по размеру.
решение1
Поскольку вы, судя по всему, работаете в системе GNU, вы можете сделать что-то вроде:
(export LC_ALL=C
find . -name '*.png' -type f -printf '%20s %p\0' |
sort -z |
uniq -zuDw20 |
cut -zb22- |
xargs -r0 echo rm -f --
)
Это выводит дополненный 20-символьный размер, за которым следует путь к файлу для каждого файла, и uniq -zuDw20
сообщает все записи, кроме последней, с дублирующимися первыми 20 байтами.
Удалите, echo
когда будете счастливы.
Вот что вы сделали неправильно:
read -d '' i
должно бытьIFS= read -rd '' i
. СмотритеПонимание «IFS= read -r line»%f
— это только имя файла, а не его полный путь, поэтому это будет работать только для имен файлов в текущем каталоге.- вы сравниваете размер файла с размером предыдущего файла, но вы сортируете список файлов по имени, а не по размеру. Поэтому файлы с одинаковым размером не обязательно будут последовательными в этом списке.