xargsを使用して複数のパターンをgrep

xargsを使用して複数のパターンをgrep

grepしたい用語を含むファイルがあり、各用語はファイルの1行です。 xargsを使用すると、これを行うことができると思います。このようなマニュアルページの例から何が得られますか?

find ./work -print0 | xargs -0 rm

例 xargs は、辞書パイプ・コマンドの出力を引数の末尾に追加します。したがって、findが返されるとreport.docxargsが生成されますrm report.doc。この理解は正しいですか?

したがって、ファイルの値がgrepコマンドの途中にあることを望むので、プレースホルダを指定する必要があります。遊んでみましたが、{}成功しませんでした。

$> cat strings.txt | xargs grep {} subdirectory/*
grep: string1: No such file or directory
grep: string2: No such file or directory

xargsは正しいツールですか?それでは構文は何ですか?

ベストアンサー1

はい、find ./work -print0 | xargs -0 rmそのようなことが起こりますrm ./work/a "work/b c" ...。使用echoして確認find ./work -print0 | xargs -0 echo rmできますecho

xargs名前を途中に入れるには、パラメータに置き換える項目が-I[string]どこにあるかを追加する必要があります。この場合は、たとえばを使用します。[string]-I{}<strings.txt xargs -I{} grep {} directory/*

実際に使いたいものは次のとおりですgrep -F -f strings.txt

-F, --fixed-strings
  Interpret PATTERN as a  list  of  fixed  strings,  separated  by
  newlines,  any  of  which is to be matched.  (-F is specified by
  POSIX.)
-f FILE, --file=FILE
  Obtain  patterns  from  FILE,  one  per  line.   The  empty file
  contains zero patterns, and therefore matches nothing.   (-f  is
  specified by POSIX.)

したがって、リテラルとしてgrep -Ff strings.txt subdirectory/*表示されるすべての文字列がstrings.txt見つかります。その-Fオプションを削除すると、ファイルで正規表現を使用できます。実際、あなたgrep -F "$(<strings.txt)" directory/*もそれを使うことができます。練習したい場合は、find要約にある最後の2つの例を使用してください。最初のレベル検索ではなく再帰検索を実行する場合は、要約にもいくつかのオプションがあります。

要約:

# grep for each string individually.
<strings.txt xargs -I{} grep {} directory/*

# grep once for everything
grep -Ff strings.txt subdirectory/*
grep -F "$(<strings.txt)" directory/*

# Same, using file
find subdirectory -maxdepth 1 -type f -exec grep -Ff strings.txt {} +
find subdirectory -maxdepth 1 -type f -print0 | xargs -0 grep -Ff strings.txt

# Recursively
grep -rFf strings.txt subdirectory
find subdirectory -type f -exec grep -Ff strings.txt {} +
find subdirectory -type f -print0 | xargs -0 grep -Ff strings.txt

-l実際の行を表示する必要がない場合は、このオプションを使用して一致する各ファイルの名前のみを取得できます。

-l, --files-with-matches
  Suppress  normal  output;  instead  print the name of each input
  file from which output would normally have  been  printed.   The
  scanning  will  stop  on  the  first match.  (-l is specified by
  POSIX.)

おすすめ記事