シェルによる拡張

シェルによる拡張

複数のサブディレクトリがあるディレクトリがあります。持つ圧縮ファイルに関する質問これには、私のニーズに合わせて少し変更した答えが含まれています。

for i in */; do zip "zips/${i%/}.zip" "$i*.csv"; done

ところで、奇妙な問題にぶつかりました。存在しない最初のフォルダセットの場合、zips/<name>.zip次のエラーが発生します。

zip error: Nothing to do! (zips/2014-10.zip)
        zip warning: name not matched: 2014-11/*.csv

しかし、ただechozipステートメントを使用する場合:

for i in */; do echo zip "zips/${i%/}.zip" "$i*.csv"; done

その後、echoコマンド(zip zips/2014-10.zip 2014-10/*.csv)を実行して正常に動作し、フォルダを圧縮しました。興味深い部分は、元のコマンドの後続の実行です。〜する最初は機能しなかったフォルダを圧縮することは実際に可能です!

この動作を直接テストするには:

cd /tmp
mkdir -p 2016-01 2016-02 2016-03 zips
for i in 2*/; do touch "$i"/one.csv; done
for i in 2*/; do touch "$i"/two.csv; done
zip zips/2016-03.zip 2016-03/*.csv
for i in 2*/; do echo zip "zips/${i%/}.zip" "$i*.csv"; done
for i in 2*/; do zip "zips/${i%/}.zip" "$i*.csv"; done

echoが次の文を印刷するのを見ることができます。

zip zips/2016-01.zip 2016-01/*.csv
zip zips/2016-02.zip 2016-02/*.csv
zip zips/2016-03.zip 2016-03/*.csv

しかし、実際のzipコマンドは次のことを伝えます。

        zip warning: name not matched: 2016-01/*.csv

zip error: Nothing to do! (zips/2016-01.zip)
        zip warning: name not matched: 2016-02/*.csv

zip error: Nothing to do! (zips/2016-02.zip)
updating: 2016-03/one.csv (stored 0%)
updating: 2016-03/two.csv (stored 0%)

.csvしたがって、実際にはzipファイルを含むsでzipファイルを更新しますが、いいえzipファイルを作成するとき。 zipコマンドのいずれかをコピーする場合:

$ zip zips/2016-02.zip 2016-02/*.csv
adding: 2016-02/one.csv (stored 0%)
adding: 2016-02/two.csv (stored 0%)

その後、zip-all-the-thingsをもう一度実行してください。

for i in 2*/; do zip "zips/${i%/}.zip" "$i*.csv"; done

2016-02と更新されました2016-03。これは私の結果ですtree

.
├── 2016-01
│   ├── one.csv
│   └── two.csv
├── 2016-02
│   ├── one.csv
│   └── two.csv
├── 2016-03
│   ├── one.csv
│   └── two.csv
└── zips
    ├── 2016-02.zip
    └── 2016-03.zip

また、驚くべきことに、これはうまくいきます。

zsh -c "$(for i in 2*/; do echo zip "zips/${i%/}.zip" "$i*.csv"; done)"

私がここで何を間違っているのか? (参考までに私はbashの代わりにzshを使用しています。違いがある場合)

ベストアンサー1

シェルによる拡張

周囲の引用が"$i*.csv"異なります。引用符を使用すると、シェルは文字列を「2014-11/*.csv」に拡張します。正確なファイルが存在せず、zipエラーが報告されます。引用符がない場合、*拡張も実行され(ファイル名拡張/「globbing」を介して)、結果zipコマンドはそれぞれ別々の引数で一致するファイルの完全なリストです。以下を使用して、ループ内で2番目の動作を取得できますfor

for i in */ ; do zip "zips/${i%/}.zip" "$i"*.csv ; done

zip拡張を通じて

zipワイルドカードを独自に拡張することも可能ですが、すべての場合にそうではありません。 ~からジッパー手動:

これ圧縮プログラムは、次の名前に対して同じ一致を実行できます。圧縮アーカイブが変更されたか、- X(除く)または-私(include)オプションは、作業するファイルのリストにバックスラッシュまたは引用符を使用して名前拡張を実行しないようにシェルに指示します。

アーカイブが正常に作成された後、元のコマンドはzip既存のアーカイブの内容とワイルドカードを一致させようとするため、後続の試行で機能します。それらはそこに存在し、まだファイルシステムに存在するので、最終的にupdating:

zipワイルドカードを取得するには作る-r(recurse)オプションを使用して、要求されたディレクトリに再帰的にアーカイブし、パターンに一致する-iファイルに制限(含める)します。

 for i in */ ; do zip -r "zips/${i%/}.zip" "$i" -i '*.csv' ; done

おすすめ記事