단어 목록이 포함된 단락 찾기

단어 목록이 포함된 단락 찾기

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. 두 번째 코드 예제는 첫 번째 코드 예제와 유사하지만 Raku의 새로운 "Junction" 연산자가 포함되어 있습니다 all. Raku에는 all, any, one및 4개의 "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의 답변에서와 같이 한 줄에 하나의 "패턴"을 가정).

~$ 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

관련 정보