.mp3
そのフォルダに一致するファイルがないディレクトリ階層のファイルと、.jpg .pngファイルにそのファイルがない階層の他のファイルを削除する方法を見つけようとしています。 )/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
これまで、私は最初の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
' {} +
答え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