サブディレクトリを含まない各ディレクトリに、そのディレクトリの内容を含むzipファイルを配置しようとしています。
次のコマンドは、ディレクトリ名および/またはファイル名にスペースがない場合は機能しますが、スペースがある場合は失敗します。
find pictures/ -type d -links 2 -execdir sh -c "pwd; echo '{}'; zip -v '{}/{}.zip' '{}/*' -x \*.zip -x \*.id" \;
いつものように「{}」を引用したので、なぜ失敗するのか理解できません。 「{}」も試しました。つまり、A / B / C / *の内容を使用してA / B / C / C.zipを生成する必要があります。 「C」にスペースがある場合は、次のような結果が得られます。
zip warning: name not matched: ./C/*
zip error: Nothing to do! (./C/./C.zip)
ベストアンサー1
あなたのバージョンでは、文字列のはfind
ファイル{}
名に置き換えられます。文字列の一部として使用すると、{}
ファイル名が挿入される方法なので、ほとんど常にエラーが発生します。ここで、ファイル名はシェルスクリプトの断片として使用されます。名前の付いたディレクトリがある場合、a'$(touch wibble)'
コマンドはシェルコードを実行します。
pwd; echo 'a'$(touch wibble)''; zip -v 'a'$(touch wibble)'/a'$(touch wibble)'.zip' 'a'$(touch wibble)'/*' -x \*.zip -x \*.id"`
コマンドがどのように実行されるかを確認してくださいtouch wibble
(4回)。
ファイル名をシェルフラグメントの引数として渡す必要があります。これはシェルを確実に使用find -exec
または呼び出す唯一の方法です(ファイル名がスペースを含む特殊文字に限定されない限り)。find -execdir
その後の最初のパラメータsh -c SCRIPT
はスクリプトから"$0"
。
また、zip
圧縮するファイルのリストにはワイルドカードは許可されていないため、シェルで拡張するにはワイルドカードを引用符で囲む必要があります。
find pictures/ -type d -links 2 -execdir sh -c 'pwd; echo "$0"; zip -v "$0/$0.zip" "$0/"* -x \*.zip -x \*.id' {} \;