我在名为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
请注意,模式被解释为 perl 正则表达式,而不是像 in 那样的基本正则表达式sed
或像 in 那样的扩展正则表达式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 中有四个“Junction”运算符:all
、any
、one
和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/language/quoting
https://docs.raku.org/type/Junction
https://raku.org