试图弄清楚如何删除目录层次结构中.mp3
在相应文件夹中/out/
没有匹配的任何文件......以及层次结构中在.jpg .png`中没有相应文件的任何其他文件, ETC。).flac
/in/
/out
/in/'. The only extension to mutate here are those two but there will be other files (like
,
#!/bin/bash
find /in>/tmp/in.txt
sed 's/.flac/.mp3/g; s+/in+/out+g' /tmp/in.txt>/tmp/inx.txt
find /out>/tmp/out.txt
grep -vxF -f /tmp/inx.txt /tmp/out.txt>/tmp/clean.txt
while read line; do rm "$line"; done < /tmp/clean.txt
最后清理空文件夹。这一行是一种“作弊”来删除任何空目录。如果上面的“rm”可以用来删除上面的文件或文件夹会更好,但这会很危险吗?
find /out/. -depth -type d -exec rmdir {} + 2>/dev/null
到目前为止,我已经发现前 2 个可以这样混为一谈:
find /in | sed 's/.flac/.mp3/g; s+/in+/out+g'>/config/inx.txt
我尝试使用:
grep -vxF -f /tmp/inx.txt `find /out`>/tmp/clean.txt
但我得到了错误:参数列表太长。
有没有办法将所有这些东西放在一起并节省一些处理时间?到目前为止,完成该操作需要将近 10 分钟。
下一次尝试,除了在带有单引号的文件/文件夹上工作(IFS 至少让它处理空格):
#!/bin/bash
IFS=$'\n'; set -f
for mp in $(find /out)
do
mf="${mp%/out/}/in/" # Change /out/ to /in/
ff="${mf%mp3}flac" # Convert mp3 filename to flac
[[ ! -f "$ff" ]] && echo rm "$mp"
done
unset IFS; set +f
好吧。我觉得这就是。在这一点上,编辑了我原来的问题,以反映它检查的不仅仅是音乐文件。
#!/bin/bash
find /out -type f -name '*' -exec bash -c '
for mp in "$0" "$@";
do
mf="${mp#/out/}"; # Strip /out/ base prefix leaving relative pathname
if [ "${mf##*.}" = "mp3" ]; then
mf="${mf%.mp3}.flac"; # convert filename to flac if it was mp3
fi;
[[ ! -f "/in/$mf" ]] && echo rm "$mp";
done
' {} +
开始了解 bash 速记是如何工作的。
#!/bin/bash
find /out -type f -exec bash -c '
for mp in "$0" "$@";
do
mf="${mp#/out/}"; # Strip /out/ base prefix leaving relative pathname
[[ "${mf##*.}" == "mp3" ]] && mf="${mf%.mp3}.flac"; # convert filename to flac if it was mp3
[[ ! -f "/in/$mf" ]] && echo rm "$mp"; # remove /out/ file if no match
done
' {} +
你不需要使用
grep
orsed
。可以为单个目录显示该过程的本质,如下所示:由于您需要将其用于目录树,因此您需要将其依次应用于每个目录:
如果您
find
不支持-exec ... +
将 替换+
为';'
。在这两种情况下echo
,当您满意时删除它会删除正确的文件。