単語リストを含む段落を探す

単語リストを含む段落を探す

Pattern.txtというファイルに単語のリストがあります。リスト内のすべての単語を含む入力ストリームの段落を検索する必要があります。段落の単一の単語(foo)には通常、sedコードを使用します。

sed   '/./{H;$!d;}; x;/foo/!d'

しかし、単語リストでこれを行う方法がわかりません。

答え1

GNU awkを使う:

$ cat patterns.txt
foo
bar
baz
$ cat file
first paragraph foo bar

second baz bar foo

third

fourth foo baz bar

fifth baz foo

これはcat file入力ストリームを表します。

$ cat file | gawk '
    NR == FNR {pattern[++n] = $0; next}
    ENDFILE {RS = ""; ORS = "\n\n"}
    {for (i = 1; i <= n; i++) if ($0 !~ pattern[i]) next; print}
' patterns.txt -   # note the trailing hyphen
second baz bar foo

fourth foo baz bar

RS = ""空白行で区切られた段落をレコードに読み込むには、awkを変更します。

答え2

そしてperl

perl -ne '
  BEGIN {chomp(@patterns = <STDIN>); $/ = ""}
  for $p (@patterns) {next LINE unless /$p/}
  print' -- your-file < patterns.txt

sedパターンは、inなどの基本正規表現やinなどの拡張正規表現ではなく、perl正規表現として解釈されますawk。ほとんどは拡張正規表現と以前のバージョンと互換性があります。

しかし、.デフォルトでは、改行は一致しません。sフラグを追加(/$p/s代わりに/$p/)して変更できます。

それ以外にも、彼らが働いているならば、awkおそらく働いているでしょうperl。 BRE または ERE には多くの拡張機能があり、その一部は段落内のマッチングに非常に便利です。たとえば、行(?m)^foo$の行を含む段落と正確に一致しますfoo。 Perl正規表現は事実上の標準となっており、その拡張の多くは、Python、PHP、PCRE、またはPCRE2を使用するすべての言語を含む、ほとんどの最新のプログラミング言語で使用できます。

答え3

使用幸せ(以前のPerl_6)

~$ raku -e 'for slurp.split("\n\n") { .put if (/foo/ & /bar/ & /baz/) };'  file

または

~$ raku -e 'for slurp.split("\n\n") { .put if all(/foo/, /bar/,  /baz/) };'  file

RakuはPerlファミリーのプログラミング言語です。上記では、ファイルをslurp編集(つまり一度に読み取る)して段落別に区切ります\n\n。これらの段落要素は次のように繰り返され、for適切ifな正規表現と一致します(&ブール値を使用)。そして演算子)、段落が終了しましたput。 2番目のコード例は最初のコード例と似ていますが、Rakuの新しい「Junction」演算子が含まれていますall。 Rakuにはall、、、anyおよびone4つの「Junction」演算子がありますnone

注:段落が複数の改行で区切られている場合など、split正規表現パラメータと一緒に使用してください.split( / \n ** 2..* / )


入力例(@glenn_jackmanのおかげで):

first paragraph foo bar

second baz bar foo

third

fourth foo baz bar

fifth baz foo

出力例:

second baz bar foo
fourth foo baz bar

「パターン」を入力ファイルとして使用する: 上記のパターンマッチングを作成したくない場合は、上記のコードの前にスペースで区切られたリストを追加できます(「単語参照」オプションは下部の最初のリンクを参照)。

~$ raku -e 'my @words = <foo bar baz> ; for slurp.trim.split("\n\n") { .put if .match: all @words };'  file

あるいは、ファイルから直接「パターン」を読み取ることもできます(@glenn_jackmanの答えと同じように、1行に1つの「パターン」と仮定)。

~$ raku -e 'my @words = "patterns.txt".IO.lines; for slurp.trim.split("\n\n") { .put if .match: all @words };'  file

テストモード入力ファイルでスペースで区切られた「単語」のみを使用したい場合は、上記の入力行を次のように単純化できます。

my @words = "patterns.txt".IO.words;


https://docs.raku.org/言語/quoting
https://docs.raku.org/type/Junction
https://raku.org

関連情報