试图弄清楚如何删除目录层次结构中在相应文件夹中没有匹配的任何.mp3
文件...以及层次结构中在.jpg .png`中没有相应文件的任何其他文件, ETC。)/out/
.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
到目前为止,我已经发现前两个可以合并在一起,如下所示:
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
' {} +
答案1
您不需要使用grep
或sed
。可以像这样针对单个目录显示该过程的本质:
#!/bin/bash
for op in /out/*.mp3
do
mp="${mp##/out/}" # Strip /out/ base prefix leaving relative pathname
fp="${mf%.mp3}.flac" # Convert mp3 name to flac
[[ ! -f "/in/$fp" ]] && echo rm "$op"
done
由于您需要将其用于目录树,因此您需要依次将其应用于每个目录:
find /out -type f -name '*.mp3' -exec bash -c '
for mp in "$0" "$@";
do
mp="${mp#/out/}";
fp="${mf%.mp3}.flac";
[[ ! -f "/in/$fp" ]] && echo rm "$op";
done
' {} +
如果您find
不支持,-exec ... +
请将其替换+
为';'
.在这两种情况下,echo
当您感到高兴时,它会删除正确的文件,然后删除。