GNU/Linux >> Linux の 問題 >  >> Linux

Findの出力をループするのはなぜ悪い習慣なのですか?

この質問は

に触発されています

シェルループを使用して、悪い習慣と見なされるテキストを処理するのはなぜですか?

これらの構成が表示されます

`find内のファイルの
for file in `find . -type f -name ...`; do smth with ${file}; done

および

for dir in $(find . -type d -name ...); do smth with ${dir}; done

なぜこの種の投稿を避けるべきなのかを説明するために時間をかけて投稿にコメントする人がいたとしても、ここではほぼ毎日使用されています…
そのような投稿の数を見る(そして時々それらのコメントが単純であるという事実無視)私は質問したほうがいいと思いました:

findをループしているのはなぜですか の出力の悪い習慣と、findによって返されるファイル名/パスごとに1つ以上のコマンドを実行する適切な方法は何ですか。 ?

承認された回答:

問題

for f in $(find .)

互換性のない2つのものを組み合わせます。

find 改行文字で区切られたファイルパスのリストを出力します。その$(find .)を離れるときに呼び出されるsplit+glob演算子 そのリストコンテキストで引用符で囲まれていない場合は、$IFSの文字で分割されます (デフォルトでは改行が含まれますが、スペースとタブ(およびzshのNULも含まれます) ))そして、結果の各単語に対してグロビングを実行します(zshを除く) )(さらに、ksh93またはpdksh派生物のブレース拡張も!)

あなたがそれを成し遂げたとしても:

IFS='
' # split on newline only
set -o noglob # disable glob (also disables brace expansion in pdksh
              # but not ksh93)
for f in $(find .) # invoke split+glob

改行文字はファイルパス内の文字と同じように有効であるため、これはまだ間違っています。 find -printの出力 単純に後処理を確実に行うことはできません(ここに示すように複雑なトリックを使用する場合を除きます)。 。

これは、シェルがfindの出力を保存する必要があることも意味します 完全に実行してから、ファイルのループを開始する前に、分割してグロブします(これは、その出力を2回目にメモリに保存することを意味します)。

find . | xargs cmd 同様の問題があります(空白、改行、一重引用符、二重引用符、円記号があります(xargもあります)。 有効な文字の一部を形成しない実装バイト)は問題です)

より正しい代替案

forを使用する唯一の方法 findの出力をループします zshを使用することになります IFS =$'をサポートします

Linux
  1. 出力の検索を制限し、信号13を回避しますか?

  2. Findが「-execCp{}Dir +」を受け入れないのはなぜですか?

  3. 終了した後、なぜPingの出力があるのですか?

  1. ls -l 出力の各行を繰り返す

  2. スペースを含むファイルのリストを反復処理する

  3. 別のコマンドのパラメーターとしての Linux コマンド出力

  1. Ssh – FirefoxがSshよりも遅いのはなぜですか?

  2. Ssh -tオプションがリダイレクト出力にCrとLfを追加するのはなぜですか?

  3. Linux 検索結果を rm にパイプできないのはなぜですか?