Grep 查找以模式文件中的字符串开头的行

Grep 查找以模式文件中的字符串开头的行

我有一个文件(模式文件),我想通过 提供给 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

替代方案:您可以使用 awk 而不是 grep 来进行匹配:

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

以上是用 Raku(Perl 编程语言家族的成员)编写的答案。假设这里的pattern_file.txt是固定字符串而不是基本的正则表达式,Raku 有字符串匹配函数,如starts-withends-with。乐库也有路口anyallonenone一样可以简化这个匹配问题。

上面-ne使用了非自动打印命令行标志,它逐行读取输入文件。在BEGIN块中将其pattern_file.txt读入@a数组。在代码正文中,如果输入行以(第一个答案)的元素put开头,则输入行将退出。或者(第二个答案),Raku 的归约元运算符符号用于在概念上插入一个any@a[ ]| 或者的元素之间的运算符@a。第一个和第二个答案给出相同的结果。

输入示例:

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/language/operators#Reduction_metaoperators
https://raku.org

答案4

执行此操作的一个选项是首先修改模式文件,使用如下所示的命令将字符添加^到每行的开头。这将指示 grep 通过正则表达式仅匹配行的开头。

awk '{print "^" $0}' PATTERN_FILE

然而,这会修改模式文件,我更喜欢一个不会​​改变原始列表的解决方案

相关内容