Сортировка файлов для использования в цикле for в файле bash

Я пытаюсь удалить дубликаты из каталога с 20k файлами. Я полагал, что дубликаты файлов, хотя и имеют разные имена файлов, имеют одинаковый размер файла. Поэтому я хочу сначала отсортировать их по размеру файла, а затем подать их один за другим в цикл for-to-to, чтобы сравнить размер текущего с размером предыдущего файла. Проблема в том, что имена файлов содержат пробелы, что делает обработку слишком сложной для меня, потому что я в конечном итоге получаю, что имена файлов разделяются на отдельные аргументы. Я попробовал два разных подхода: 1.

last=0
for filename in *
do
current=`du -b "${filename}" | cut -f1`
    if [ $current -eq $last ] 
    then
        rm "$filename"
    fi
last=$current
done

Это работает, если дубликаты появляются сразу после друг друга. А так как сортировка по умолчанию не соответствует их размеру, остается много дубликатов.

2.

last=0
for filename in `ls -AS`
do
current=`du -b "${filename}" | cut -f1`
    if [ $current -eq $last ] 
    then
        rm "$filename"
    fi
last=$current
done

Это не работает, потому что имена файлов не передаются в «имя файла» правильно, а разбиваются на части, поскольку каждый пробел рассматривается как разделитель. Как я могу объединить два метода?

1
задан 11 May 2019 в 21:37

1 ответ

Хотя я согласен с тем, что использование таких утилит, как md5sum и shasum, намного более эффективно, чем размер файла, при обнаружении дубликатов (как уже упоминалось в комментариях), корень этого вопроса, по-видимому, больше о том, как сортировать файлы, когда пробел включен в имя. Я полагаю, что вы можете использовать ls -S1, чтобы сделать то, что вам нужно, поскольку это поместит вывод из ls с одним именем файла на логическую строку (отсортировано по размеру). Если вы затем измените переменную IFS для перехода на новую строку, у вас должно получиться то, что вам нужно. Ниже приведен пример кода, иллюстрирующего:

ORIG_IFS="${IFS}"
IFS= 

Если вы решите использовать md5sum или shasum, вместо этого вы увидите, что вывод команды печатает хеш в начале каждой строки вывода, после чего следует имя файла Затем вы можете sort вывести результат (который поместит дублирующие строки хеша рядом друг с другом), использовать команду cut, чтобы очистить хеш фиксированной длины от начала строки, и обработать так, как вы пытаетесь сделать с размером файла.

\n' for CURR_FILE in $(ls -S1) do echo "Next file: ${CURR_FILE}" done IFS="${ORIG_IFS}"

Если вы решите использовать md5sum или shasum, вместо этого вы увидите, что вывод команды печатает хеш в начале каждой строки вывода, после чего следует имя файла Затем вы можете sort вывести результат (который поместит дублирующие строки хеша рядом друг с другом), использовать команду cut, чтобы очистить хеш фиксированной длины от начала строки, и обработать так, как вы пытаетесь сделать с размером файла.

0
ответ дан 11 May 2019 в 21:37

Другие вопросы по тегам:

Похожие вопросы: