質問: シェルスクリプトで空白やその他の特殊文字が詰まるのはなぜですか? または、堅牢なファイル名の処理とシェルスクリプトで渡されるその他の文字列の入門ガイド。私はほとんどの場合うまくいくシェルスクリプトを書きました。しかし、一部の入力(ファイル名など)で窒息します。次のような問題が発生しました。 スペースを含むファイル名がありますhello world、それは2つの別々のファイルhelloおよびworldとして扱われました。 2つの連続するスペースがある入力ラインがあり、入力で1つに縮小されました。 先頭と末尾の空白は入力行から消えます。 場合によっては、入力に\[*?、それらは実際にはファイルの名前であるテキストに置き換えられます。 アポストロフィがあります'(または二重引用符")入力で、その後は奇妙になりました。 入力にバックスラッシュがあります(または、cygwinを使用していて、ファイル名の一部にwindowsスタイルの\セパレーター)。 何が起こっているのですか、どうすれば修正できますか?
回答: ファイル名にスペースが含まれ、ディレクトリ名にスペースが含まれる大規模なビデオプロジェクトがありました。 find -type f -print0 | xargs -0はいくつかの目的でさまざまなシェルで機能しますが、bashを使用している場合は、カスタムifs(入力フィールド区切り記号)を使用すると柔軟性が高まることがわかります。以下のスニペットはbashを使用し、ifsを改行に設定しています。ファイル名に改行がない場合:(ifs=$'\n'; for i in $(find -type f -print) ; do echo ">>>$i<<<" done) 括弧を使用してifsの再定義を分離することに注意してください。 ifsを回復する方法について他の投稿を読んだことがありますが、これは簡単です。さらに、ifsを改行に設定すると、シェル変数を事前に設定して簡単に印刷できます。たとえば、区切り文字として改行を使用して変数vを段階的に大きくすることができます。v="" v="./ralphie's camcorder/stream/00123.mts,04:58,05:52,-vf yadif" v="$v"$'\n'"./ralphie's camcorder/stream/00111.mts,00:00,59:59,-vf yadif" v="$v"$'\n'"next item goes here..." それに応じて:(ifs=$'\n'; for v in $v ; do echo ">>>$v<<<" done) これで、二重引用符を使用してecho "$v"でvの設定を「リスト」し、改行を出力できます。 ($'\n'の説明については this thread にクレジットしてください。)