リストファイルにスペースを含むファイル名を「grep」にパイプする方法は?

リストファイルにスペースを含むファイル名を「grep」にパイプする方法は?

まず、私はcygwinを使用しているという事実はここで非常に関連性が高いと思います。

理論的には、私はこれを行う方法をすでに知っています。

cat file | xargs grep pattern

問題は、一部のファイルパスfileにスペースがあることです。ファイルは次のようになります。

subdir/foo/bar.html
subdir/f o o/ba r.html
subdir/~foo/bar.html

これによりエラーが発生します。この問題を解決する方法を読んだ。 use 。しかし、出力をnullで終わる行にxargs -0する方法がわからないので、ファイル全体を1行に圧縮するという意味だと思いました。catその結果、次のエラーが発生します。

xargs: argument line too long

修正する:私が読んでいたファイルにはもう存在しないいくつかのパスがあることがわかりました。偶然にも、これらの道はすべて一つずつあり、~これが問題だと思います。この文書は存在しないことがわかりました。それでも宇宙に関するすべてが残っています。

答え1

xargs -d '\n'入力ファイルに1行に1つのファイル名が含まれている場合に使用されます。例えば

xargs -d '\n' grep pattern < file

ファイル名が「マイホームディレクトリ」で始まる場合は、まずこのシンボルを実際のホームディレクトリに変更する必要があり~ます。~たとえば、

sed -e "s=^~=$HOME=" file | xargs -d '\n' grep pattern

このsedスクリプトは二重引用符で囲まれています。考える変数を$HOMEsedスクリプトに挿入し、/ sが含まれているため、これを演算子の区切り文字として使用します(=しかしそうである可能性は低い)。s$HOME=

またはを使用している場合は、xargsオプションと一緒にfindfindオプションを使用してください。例えば-print0-0

find ... -print0 | xargs -0 grep pattern

または単にfind-execオプションを使用してください:

find ... -exec grep pattern {} +

答え2

他の答えで述べたように、xargs -d '\n'これが好ましい解決策です。 (私の考えにはこれが望ましいと思いますxargs基本しかし、それは別の話です。 )

ただし、すべてのバージョンがxargsサポートされているわけではありません-d。うまくいかない方法に閉じ込められている場合は、試してみてください。

tr '\n' '\0' < file | xargs -0 grep pattern

(昔はtrこのようにヌル文字を置き換えることができないバージョンがありましたが、今日ではこれらの文字に触れる可能性はほとんどありません。)

答え3

覚えておいてください:xargsファイルの内容全体はgrepのコマンドライン引数として使用されます...あなたが受け取るエラーは、ファイル内のファイル名が多すぎるため、コマンドラインが長すぎる可能性があります。

コンテンツがパターンに一致するファイルを検索するには、次の繰り返しアプローチを使用することをお勧めします。

gcolangelo@debian-test:/tmp$ cat test_files 
/dir1/file1 with space
/dir2/file2 with space
/dir3 with space/file3

gcolangelo@debian-test:/tmp$ while read filepath ; do echo "-- coin ${filepath} --" ; done < test_files 
-- coin /dir1/file1 with space --
-- coin /dir2/file2 with space --
-- coin /dir3 with space/file3 --
-- coin  --

答え4

場合によっては、whileループを使用する方が良いかもしれませんxargs(たとえば、複数のコマンドを実行したい場合など)。

while IFS= read -r file <&3
do
    grep -- pattern "$file" 3<&-
done 3< file

grepただし、ファイルごとに1つずつ呼び出すことに注意してください。

関連情報