何百ものファイルのリストに対してgrepを実行しようとしています。
$ head -n 3 <(cat files.txt)
admin.php
ajax/accept.php
ajax/add_note.php
ただし、ファイル内で見つかったことがわかっている文字列を探していても、以下はファイルを検索しません。
$ grep -i 'foo' <(cat files.txt)
$ grep -i 'foo' admin.php
The foo was found
私は旗についてよく知っており、-f
次のように読みます。模様ファイルから。しかし、どうやって読むべきですか?入力ファイル?
cp
私はその形式をサポートしているように見える一時ディレクトリに<(cat files.txt)
ファイルをコピーし、そこからファイルをインポートする恐ろしい解決策を検討しました。Shirleyにはより良い方法があります。
答え1
ファイル自体ではなくファイル名のリストを探しているようです。<(cat files.txt)
ファイルをリストするだけです。<(cat $(cat files.txt))
実際に接続して単一のストリームで検索してみてください。または
grep -i 'foo' $(cat files.txt)
すべてのファイルにgrepを提供します。
ただし、リストにファイルが多すぎると、パラメータ数に問題が発生する可能性があります。それを書くだけ
while read filename; do grep -Hi 'foo' "$filename"; done < files.txt
答え2
xargs grep -i -- foo /dev/null < files.txt
ファイルがスペースまたは改行で区切られているとします(引用符またはバックスラッシュを使用してこれらの区切り文字をエスケープできます)。 GNU ではxargs
区切り文字を指定できます-d
(ただし、引用符は無効になります)。
(unset -v IFS; set -f; grep -i -- foo $(cat files.txt))
ファイルはスペース、タブ、または改行で区切られていると想定されます。に割り当てて別の区切り文字を選択することはできますが、これらの区切り文字を外す方法はありませんIFS
。ほとんどのシステムでファイルのリストが大きすぎると、操作は失敗します。
また-
。
答え3
標準入力からファイル名のリストを読み取るには、次のものを使用できますxargs
。
cat files.txt | xargs -d'\n' grep -i -- 'foo'
デフォルトでは、xargs
エントリはスペースで区切られた標準入力から読み取られます。-d'\n'
スペースを含むファイル名を処理できるように、改行文字をパラメーター区切り文字として使用するように指示します。 (Stéphane Chazelasが指摘したように、これはGNU拡張です。)しかし、改行文字を含むファイル名は処理できません。これを処理するには、より複雑な方法が必要です。
FWIW、この方法はwhile read
bashのコマンドが非常に遅いため、ループより少し高速ですread
。データを文字ごとに読み込み、xargs
入力を読み取る方がはるかに効率的です。また、必要なだけコマンドを呼び出すだけです。xargs
各呼び出しは複数のファイル名を受け取るため、各ファイル名に対して個別に呼び出すよりも効率的です。grep
grep
よりxargs のマニュアルページ詳細については、xargs情報ページを参照してください。
答え4
xargs
files.txt
これらのオプションを使用して、ファイルから項目(リストなど)を読み取ることができます。
--arg-file=file
-a file
Read items from file instead of standard input. If you use this
option, stdin remains unchanged when commands are run. Other‐
wise, stdin is redirected from /dev/null.
したがって、この方法も機能します。
xargs -a files.txt grep -i 'foo'
またはファイル名にスペースが含まれています
xargs -d'\n' -a files.txt grep -i 'foo'
xargs -I{} -a files.txt grep -i 'foo' {}