私はUnixに初めてアクセスし、CygWIN64エミュレータを使用しています。特定の文字列を検索するために必要な数のテキストファイルがあります。私は単一の文字列を使用して検索する方法を正常に学びましたが、数日間試しても2つの文字列を検索する方法はわかりません。
私のファイルは次の場所にあります。c:/BF/data/
私の単一文字列コマンドは次のとおりです。
grep -Rinw c:/BF/data/ -e 'string'
オンラインの例をたくさん試しましたが、2つの文字列を処理するコマンドを取得できません(OR構造ではなくAND構造)。これら2つの文字列が1行に表示される場合は、その行を画面に表示したいと思います。今回もひもひとつでこれを行うことができました。文字列にスペースが含まれている可能性があります(これが違いがある場合)。例えば、ある文字列は「ミアミ」であり、他の文字列は「ニューヨークシティ」であってもよい。
grep
別のコマンドを試しましたが、awk
何も機能しません。
誰かが私に正しい方向を教えてもらえますか?
答え1
1行で2つの文字列を見つけるには:
Perl互換の正規表現でGNU grepを使用してください。
grep -RinP '^(?=.*\bMiami\b)(?=.*\bNew York City\b)' dir/
\b
単語の境界として使用されるPerl正規表現。
GNU awkを使う:
gawk -v IGNORECASE=1 '
/\<Miami\>/ && /\<New York City\>/ {
print FILENAME ":" NR ":" $0
}
' file
拡張正規表現は単語の境界線とを\<
使用します。\>
ただし、awkに対応する項目はありません-R
。 find を使用できます。
find dir/ -type f -exec gawk -v IGNORECASE=1 '...' '{}' +
答え2
次の回避策は、@Campaによって提供された@steeldriverによってリンクされた投稿にあります。
grep -Rinw Miami . | grep -iw "new york city"
再帰的な検索と出力を得るには、スイッチを追加するだけです。
使用
Miami banana
Miami New York City
Miami banana
New York City banana
Miami banana
New York City Miami
ファイルが多い場合は、P
erlを使用しないことをお勧めしますgrep
。
time grep -Rinw Miami . | grep -iw "new york city"
./file:2:Miami New York City
./file:6:New York City Miami
real 0m0.014s
user 0m0.004s
sys 0m0.016s
time grep -RinwP Miami . | grep -iwP "new york city"
./file:2:Miami New York City
./file:6:New York City Miami
real 0m0.059s
user 0m0.060s
sys 0m0.004s
上記は@glennjackmanとerltime
に比べて利点があるようです。P
time grep -RinP '^(?=.*\bMiami\b)(?=.*\bNew York City\b)' .
./file:2:Miami New York City
./file:6:New York City Miami
real 0m0.069s
user 0m0.062s
sys 0m0.007s
同じ検索を1,000回繰り返すと、for i in {1..1000}; do ....; done
これが確認されるようです。
P
おじさんgrep
real 0m49.276s
user 0m47.414s
sys 0m1.790s
P
@カンパエルgrep
real 0m42.841s
user 0m42.305s
sys 0m3.346s
@campa シンプルgrep
real 0m8.813s
user 0m8.837s
sys 0m3.081s
しかし、1,000回スプリントの勝者は@glennjackmanです。awk
real 0m2.975s
user 0m2.259s
sys 0m0.772s