我的~/Music/
目录实际上充满了我想要清理的“空”目录。我说“空”是因为这个目录实际上包含文件,有些包含旧的封面图像文件或Thumbs.db files
.
我想递归删除所有这些目录内部不包含任何音乐文件或其他目录。
例如~/Music/Audioslave/包含很多带有专辑名称的目录,但没有音乐文件,但我不想删除它,因为里面有音乐文件。如果 oldalbum 目录中没有音乐文件或其他目录,我想删除 ~/Music/Audioslave/oldalbum/ 。
答案1
一个有趣的解决方案涉及find
a 内部find
,但比接受的答案更安全(我个人不喜欢解析命令的输出,是ls
或find
,特别是在没有预防措施的情况下)。以下命令将打印不包含任何内容的文件夹音乐文件(这里,音乐文件意味着具有扩展名mp3
、flac
、ogg
或wav
,m4a
但可以随意添加更多):
find . -depth -type d \! -exec sh -c 'find "$1" \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.ogg" -o -iname "*.wav" -o -iname "*.m4a" \) -type f | read a' _ {} \; -print
你应该在你的系统上尝试这个,当你对它的行为方式感到满意时,将最后的替换-print
为-exec rm -rfv -- {} \;
此处使用文件名的方式使得此方法对于带有有趣符号(即空格、引号、换行符、尾随换行符、前导和尾随空格等)的文件名而言 100% 安全。
答案2
我在 SO 上找到了这个例子,标题为:终端 - 删除所有不包含 .mp3 文件的文件夹。
#! /bin/bash
find -depth -type d | while read -r D
do
v=$(find "$D" -iname '*.mp3')
case "$v" in
"" )
echo "$D no mp3"
# rm -fr "$D" #uncomment to use
;;
esac
done
例子
样本数据。
.
|-- 1
| |-- 1.mp3
| `-- 1.txt
|-- 2
| `-- 2.mp3
|-- 3
| `-- 3.txt
|-- 4
| `-- 4.txt
|-- 5
| `-- 5.mp3
|-- 6
| `-- 61
| `-- 61.mp3
|-- 7
| `-- 71
| `-- 71.txt
`-- deletenomp3.bash
样品运行
如果我运行它,它将删除以下内容:
$ ./deletenomp3.bash
./7 no mp3
./7/71 no mp3
./4 no mp3
./3 no mp3
其他文件类型
您可以通过-name
向脚本中的第二个 find 命令添加更多参数来简单地扩展它。例如,添加.wav
文件:
v=$(find "$D" -iname '*.mp3' -o -iname '*.wav');
这就是说*.mp3
“或” *.wav
。添加更多或其他:
v=$(find "$D" -iname '*.mp3' -o -iname '*.flac' -o -iname '*.m4a');
我确信如果您有更多文件类型使用替代切换到find
.
答案3
尝试一些类似的事情(未经测试):
for dir in ~/Music/* ; do
found=false
# Add your music file extensions here.
for file in "$dir"/*.{mp3,wav} */ ; do
if ls "$file" > /dev/null 2>&1 ; then
found=true
break
fi
done
if ! $found ; then
# Remove 'echo' when you are ready.
echo rm -vrf "$dir"
fi
done
我不确定有多少 shell 支持*/
通配符。至少 Bash 和 Zsh 是这样的。