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

ファイル名にスペースが含まれている場合、find コマンドの出力を解析するにはどうすればよいですか?

シェルスクリプトでファイル名を適切に解析することは常に難しいため、理想的にはまったくそうしないでください(スペースを修正すると、他の埋め込み文字、特に改行で問題が発生します)。これは、BashPitfalls ページの最初のエントリとしてもリストされています。

そうは言っても、あなたが望むことをほとんど行う方法があります:

oIFS=$IFS
IFS=$'\n'

find . -name '*.txt' | while read -r i; do
  # use "$i" with whatever you're doing
done

IFS=$oIFS

$i も引用することを忘れないでください それを使用するときは、他のものが後でスペースを解釈するのを避けるためです。 $IFS を設定することも忘れないでください そうしないと、後で当惑するようなエラーが発生するためです。

これには、もう 1 つの注意事項があります。while 内で何が起こるかです。 使用しているシェルによっては、ループがサブシェルで発生する可能性があるため、変数の設定が保持されない場合があります。 for ループバージョンはそれを回避しますが、 $IFS を適用してもその代償があります find の場合、問題が発生します。 返されるファイルが多すぎます。

ある時点で、これらすべての正しい修正は、シェルではなく Perl や Python などの言語で行うことになります.


find -print0 を使用 xargs -0 にパイプします。 、または独自の小さな C プログラムを作成し、それを小さな C プログラムにパイプします。これが -print0 です と -0 のために発明されました。

シェル スクリプトは、スペースを含むファイル名を処理する最適な方法ではありません。実行できますが、扱いにくくなります。


「内部フィールドセパレータ」(IFS)を設定できます ) ループ引数分割のためのスペース以外の何かに、例えば

ORIGIFS=${IFS}
NL='
'
IFS=${NL}
for i in $(find . -name '*.txt'); do
    IFS=${ORIGIFS}
    #do stuff
done
IFS=${ORIGIFS}

IFS をリセットしました find で使用した後、主に見栄えが良いためだと思います。改行に設定しても問題はありませんが、これは「よりクリーン」だと思います。

find からの出力で何をしたいかによって、別の方法 、 -exec を直接使用することです find で コマンド、または -print0 を使用 xargs -0 にパイプします。 .最初のケース find ファイル名のエスケープを処理します。 -print0 で ケース、find その出力を null 区切り記号で出力し、次に xargs を出力します これで分かれます。ファイル名にその文字を含めることはできないため (私が知っていること)、これも常に安全です。これは単純な場合に最も役立ちます。通常、完全な for の代わりにはなりません。 ループ。


Linux
  1. 最初の一致後に検索コマンドを停止する方法は?

  2. コマンドラインから使用しているOsXのバージョンを確認するにはどうすればよいですか?

  3. Grub2のコマンドからの出力に等しい変数を設定するにはどうすればよいですか?

  1. Linuxのlocateコマンドとfindコマンドの違いは何ですか

  2. Linux 'w' コマンドの出力で IDLE 列を読み取る方法は?

  3. 正しい find -exec 構文は何ですか

  1. コマンドの出力をシェル変数に割り当てる方法は?

  2. Linux の find コマンドを使用してファイルを検索する方法

  3. パイプからコマンドラインで作成するときに、zip 内でファイル名を指定するにはどうすればよいですか?