1

私はかなり立ち往生しています。複数のファイル (拡張子 .dat) があるフォルダーのコンテンツを圧縮する必要があります。シェルスクリプトに行きました。

これまでのところ、それほど難しいことではないと自分に言い聞かせました。ディレクトリの内容を再帰的に読み取り、ファイルの名前を取得して、ファイル自体の名前を使用して圧縮するだけです。

これは私が書いたものです:

for i in *.dat; do zip $i".zip" $i; done

今試してみると、奇妙な動作が発生します。各ファイルは「12/23/2012 data102 test1.dat」のように呼び出されます。この一連のコマンドを実行すると、ファイル名全体を認識するのではなく、その zip が表示されます。文字列の各部分が単一のエンティティとして表示され、操作全体が失敗します。

私は何か間違ったことをしていて、i 変数が間違っていると自分に言い聞かせました。そのため、zip コマンドの代わりに echo を置き換えました (どれが i 変数の出力であるかを確認するため)。$i 出力は、ファイルの一部ではなく、ファイルの完全な名前です。

この時点で何が起こっているのかまったくわかりません...変数iがzipで読み取られる場合、文字列全体ではなく、文字列の各部分が読み取られますが、echoを使用してその変数の内容を確認すると正しい出力が得られます。

ファイル名の値を別の方法で zip に渡す必要がありますか? これはパラメーターとして渡される変数の内容であるため、文字列が 1 つであるかスペースが含まれているかは問題ではないと想定していましたが、man ページで答えを見つけることができません (そこに何かがある場合) )。

なぜこの動作が発生するのか、それを修正する方法を知っている人はいますか? ありがとう!

4

1 に答える 1

1

スペースが含まれているものはすべて引用する必要があります。

zip "$i.zip" "$i"

一般的に言えば、シェルで複数のトークンに分割する必要がある場合を除き、変数補間には二重引用符を付ける必要があります。内部フィールドセパレーターの$IFSデフォルトはスペースとタブですが、これを変更して、シェルが任意のセパレーターで単語分割を行うようにすることができます。シェルの引用メカニズムの詳細な説明については、適切な初心者向けシェル チュートリアルを参照してください。

于 2012-12-25T10:12:52.557 に答える