Поиск и удаление файлов с одинаковым префиксом, но с другим расширением (т. Е. * .Flac и * .mp3) - PullRequest
0 голосов
/ 11 января 2019

В моем музыкальном каталоге у меня есть несколько дубликатов файлов в формате .mp3 и .flac. Рассмотрим:

/dir1/music1.flac
/dir1/music1.mp3
/dir2/music1.mp3
/dir2/music2.MP3
/dir2/music2.flac
/dir2/music3.mp3

music1.flac и music1.mp3 в dir1 - это одна и та же песня в разных форматах, но music1.mp3 в dir1 и dir2 может не быть (одно и то же имя, но выпущено на разных альбомах).

Я хочу просмотреть несколько подкаталогов, находя файлы с одинаковым префиксом, но разными расширениями, а затем удалить только файлы mp3. Таким образом, для вышеперечисленных каталогов у меня останется:

/dir1/music1.flac
/dir2/music1.mp3
/dir2/music2.flac
/dir2/music3.mp3

Я пытался использовать команду find с логическим AND, но безрезультатно. Некоторые неудачи с моей стороны:

find ./ -regex '.*\(mp3\|flac\)$'
find . -type f -name "*mp3" -and -name "*flac"

Любая помощь приветствуется. Я самостоятельно решил подобные проблемы с размещенным кодом stackoverflow, но я озадачен этим. ВЫ, ПАРНИ, БОЛЬШОЕ.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Попробуйте этот ( Shellcheck -чистый) код:

#! /bin/bash

shopt -s nullglob   # Globs that match nothing expand to nothing
shopt -s globstar   # ** matches multiple directory levels

for mp3_path in **/*.[Mm][Pp]3 ; do
    # Find '.flac', '.FLAC', '.Flac', ..., files with the same base
    flac_paths=( "${mp3_path%.*}".[Ff][Ll][Aa][Cc] )
    if (( ${#flac_paths[*]} > 0 )) ; then
        # There is a(t least one) FLAC file so remove the MP3 file
        printf "Removing '%s'\\n" "$mp3_path"
        # rm -- "$mp3_path"
    fi
done

Требуется Bash версии 4.0 или новее, потому что он использует globstar.

Поскольку в вашем примере были прописные и строчные буквы «.mp3», код обрабатывает любой регистр «.mp3» или «.flac». Это может быть упрощено, если в этом нет необходимости.

Удалите комментарий в строке rm, чтобы фактически удалить файлы.

0 голосов
/ 11 января 2019

Это подтвердит файлы, которые будут удалены:

find . -type f|sort|awk -F ":" '{match($1,"(.+)\\.[A-Za-z0-9]+$",base); if (base[1]==prev) {fordel=$1} else {fordel=null};if (base[1]) prev=base[1]; if(fordel) {print "\"" fordel "\""}}'|xargs echo

И это будет обрабатывать удаление:

find . -type f|sort|awk -F ":" '{match($1,"(.+)\\.[A-Za-z0-9]+$",base); if (base[1]==prev) {fordel=$1} else {fordel=null};if (base[1]) prev=base[1]; if(fordel) {print "\"" fordel "\""}}'|xargs rm

Оба решения будут обрабатывать пробелы в файлах.

...