在我的音乐目录中,我有多个.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代码解决了类似的问题,但是我对此感到困惑。你们很棒。
答案 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
两个解决方案都将处理文件中的空间。