次のファイルシステム構造で:
root/
|
container1/
| |
| subdir2/
| |
| subdir3/
| |
| subdir4/
| |
| file1
| file2
| subdir5/
container2/
|...
すべてを圧縮する必要があります。
- "/subdir4/"の下
/subdir4/
それ自体なし/container/
ディレクトリ内のすべての潜在的なサブroot/
ディレクトリ- zip名を圧縮コンテンツの親フォルダと同じ名前で指定します(この場合は「subdir4.zip」)。
覚えておいてください:
- これはディレクトリとサブディレクトリの実際の名前ではなく、単なるおおよその名前です。
- Mac OSXでZSHを使用しています。
- Unix/Linux スクリプトが初めてです。
私はできるだけ多くのことを学び、他の潜在的な状況に対してこの解決策を変更する柔軟性を持たせるためにシェルに拘束されることなく、単純なループ型ソリューションを本当に望んでいます。
私が今まで試したことは次のとおりです。、友人が提供したように:
find . -mindepth 5 -maxdepth 5 -type d -exec sh -c '
pushd "$0/..";zip -rFS "$(basename "$0").zip" "$(basename "$0")";popd ' {} \;
同時に、私はこのソリューションに次の欠点があることに気づきました。
- $ 0はエラー報告および/またはシェルスクリプト名として使用されるため、位置引数として使用しないでください(私の場合は文字列にすぎません)。
basename
そしてdirname
避けてください(もっと読むここ)- この構文は
... {} \;
結果と同じくらい多くのシェルを呼び出します。
私はいつも以下を使うべきです:
- 現在地パラメータの$1
... ;popd ' sh {} +
これは、すべての結果を「配列/リスト」にインポートし、sh
すべての結果に渡された文字列のコマンドをすぐに適用する必要があります。
ありがとうございます!
ボーナスポイント::)
- 生成された.zipの名前をこの階層
/subdir3/
と同じ名前で指定できますか/subdir4/
?
答え1
awkを使用して実行するシステムコマンドを生成できます。
find * -mindepth 5 -maxdepth 5 -type d | awk -F"/" '{system( "cd "$0"; zip -rF "$NF".zip *")}'
/で-F
行を分割して$0
行全体を表し、$NF
実際のディレクトリ名を持ちます。システムコマンドは独自のシェルで実行され、親シェルは現在の作業ディレクトリに残るため、popdは必要ありません。