查找和删除前缀相同但扩展名不同的文件(即* .flac和* .mp3)

时间:2019-01-11 16:52:09

标签: bash find mp3 flac

在我的音乐目录中,我有多个.mp3和.flac格式的重复文件。考虑:

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

dir1中的music1.flac和music1.mp3是同一首歌曲,格式不同,但是dir1和dir2中的music1.mp3可能不同(名称相同,但是在不同的专辑中发行)。

我希望遍历多个子目录,以找到具有相同前缀但具有不同扩展名的文件,然后仅删除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 :(得分:1)

尝试使用此{Shellcheck-clean)代码:

#! /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

由于它使用globstar,因此需要Bash 4.0或更高版本。

由于您的示例同时包含小写和大写的“ .mp3”,因此代码可以处理“ .mp3”或“ .flac”的所有大小写。如果不需要的话,可以简化。

删除rm行上的注释,以使其实际上删除文件。

答案 1 :(得分:0)

这将确认将要删除的文件:

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

两个解决方案都将处理文件中的空间。