Вы достигли точки, в которой вы перебираете список глобусов, совпадающих с дублирующимися файлами.
Осталось только получить размер файлов, соответствующих этим глобусам, переименовать самый большой и удалить другие.
find
могут получить размеры файлов, используя соответствующие спецификаторы формата своего действия -printf
:
find . -name "$line" -printf '%p\007%s\n'
В этом printf
формате %p
относится к путь к файлу, %s
к его размеру, \n
- перевод строки, а \007
- символ ASCII BEL / Bell. Я использую это, потому что я планирую рассматривать строки как состоящие из двух полей, и я должен выбрать символ, который, как я знаю, не будет присутствовать в именах ваших файлов (или их размерах, но это легко), чтобы использовать их в качестве разделителя этих fields.
Стандартом будет использование байта NUL / Null, ASCII 0, но в этом случае я не смог его легко использовать, поэтому любой другой символ, который, я уверен, не будет найден в вашем файле имена делают свое дело. Джеймс Бонд определенно не повлиял на мой выбор.
На данный момент у меня есть список файлов, соответствующих глобусу, сопоставленному с их размером, например
./<artist_1>/<artist_1> - <song_name> (1).mp3?12345
./<artist_1>/<artist_1> - <song_name> (2).mp3?12223
./<artist_1>/<artist_1> - <song_name>.mp3?12345
(я использовал несвязанную пиктограмму UTF-8 «Колокольчик» для улучшения читабельности, где должно быть \007
)
Мне нужно отличить guish строку с наибольшим размером от другие. Одно из решений состоит в том, чтобы отсортировать эти строки численно по второму полю, разделив их числовыми сортировками \007
:
sort -grt $'\007' -k 2
-g
, -t $'\007'
позволяет нам определить, что наш разделитель полей равен \007
, -k 2
определяет второе поле как ключ сортировки, а -r
меняет порядок сортировки, что позволяет нам извлечь самый большой файл из первой строки, что проще.
Теперь нам просто нужно извлечь имя файла из В первой строке переименуйте его, затем выполните итерации по оставшимся строкам, извлеките имя файла и удалите его:
{
# read the biggest file from the first line
IFS=$'\007' read -r biggest_file its_size
mv "$biggest_file" $(sed 's/ ([0-9]*).mp3/.mp3/' <<<"$biggest_file")
# read other files
while IFS=$'\007' read -r other_file its_size; do
rm "$other_file"
done
}
Теперь, чтобы соединить части вместе:
[...]
while IFS= read -r line; do
echo "processing: $line"
{
# read the biggest file from the first line
IFS=$'\007' read -r biggest_file its_size
mv "$biggest_file" $(sed 's/ ([0-9]*).mp3/.mp3/' <<<"$biggest_file")
# read other files
while IFS=$'\007' read -r other_file its_size; do
rm "$other_file"
done
} < <(find . -name "$line" -printf '%p\007%s\n' | sort -grt $'\007' -k 2)
done < $tempfilesorted
Обратите внимание, что я не сделал не сосредотачивайтесь на действиях в этом ответе, поскольку я хотел бы развить то, что вы уже сделали, и дать чистый bash ответ, и я ожидаю, что они не будут хорошими. Если он слишком медленный на ваш вкус, вы должны оставить только первый выбор файлов до bash
и иметь более высокий уровень языка, такой как awk
, python
, perl
, et c. обрабатывать список файлов.