grepに提供したいファイル(パターンファイル)があり、-f
文字列を含む他のファイル(検索ファイル)で一致するものを見つけたいと思います。によって。 。スタート与えられたパターン。たとえば、
スキーマファイル
1234
qwerty
chicken
ファイル検索
12345
543212345
qwerty
1fwf32sgww
chicken fingers
上記のファイルが与えられた場合、grepは次の行を返す必要があります。
12345
qwerty
chicken fingers
どうすればいいですか?
答え1
転送したい^
内容をすべての行の前に追加できます。PATERN_FILE
grep -f
paste -d '^' /dev/null PATTERN_FILE | grep -f - SEARCH_FILE
またはsed 's/^/^/' PATTERN_FILE
代わりにpaste
。
現在の行がデフォルトの正規表現ではなく固定文字列である場合は、PATTERN_FILE
すべての正規表現演算子もエスケープする必要があります。
sed 's/[][$^*\\.]/\\&/g; s/^/^/' PATTERN_FILE | grep -f - SEARCH_FILE
答え2
回避策:grepの代わりにawkを使用して一致を実行できます。
awk 'NR==FNR{a[$0];next} {for(t in a) if(substr($0,1,length(t))==t){print;next}}' needles haystack
これはgrepの正規表現エンジンのオーバーヘッドを防ぎますが、awkの解釈オーバーヘッドがあります。どちらがうまくいくのかわかりません。
答え3
使用幸せ(以前のPerl_6)
~$ raku -ne 'BEGIN my @a = "/path/to/pattern_file.txt".IO.lines; \
.put if .starts-with( any @a );' search_file.txt
#OR
~$ raku -ne 'BEGIN my @a = "/path/to/pattern_file.txt".IO.lines; \
.put if .starts-with( [|] @a );' search_file.txt
上記は、Perlシリーズのプログラミング言語であるRakuで書かれた答えです。これがpattern_file.txt
デフォルトの正規表現ではなく固定文字列であると仮定すると、Rakuには、starts-with
などの文字列一致機能がありますends-with
。レクもいます。交差点any
、、all
のように、このマッチングの問題を簡素化できますone
。none
上記では、-ne
非自動印刷コマンドラインフラグが使用され、入力ファイルを1行ずつ読み込みます。ブロックの配列にBEGIN
読み込まれます。コード本文で(最初の答え)要素で始まると、入力行は終了します。または(第2回答)Rakuの縮小メタ演算子表記を使用して、概念的に以下を挿入します。pattern_file.txt
@a
put
any
@a
[ ]
|
または要素間の演算子@a
。最初と2番目の答えは同じ結果を提供します。
入力例:
pattern_file.txt
1234
qwerty
chicken
search_file.txt
12345
543212345
qwerty
1fwf32sgww
chicken fingers
出力例:
12345
qwerty
chicken fingers
one
注:結合ポイント(または同等の[^]
縮小メタ演算子)が同じことを行うと思うのは簡単ですが、これはpatterns_file.txt
各行が一意の場合にのみ当てはまります!
https://docs.raku.org/routine/starts-with
https://docs.raku.org/type/Junction
https://docs.raku.org/言語/operators#Reduction_metaoperators
https://raku.org
答え4
これを行う1つのオプションは、まず以下のコマンドを使用して^
各行の先頭に文字を追加してパターンファイルを変更することです。その後、grepは正規表現を介して行の先頭のみに一致するように指示します。
awk '{print "^" $0}' PATTERN_FILE
ただし、これはスキーマファイルを変更するため、元のリストを変更しないソリューションを好む。