unix - 包含另一个文件中的两个字符串的匹配行

标签 unix awk sed grep text-processing

我有一个文件 source.txt,其中包含两列由空格分隔的字符串。

foo bar
foo baz
goo gaa

此外,还有另一个文件 pattern.txt,它是应用作模式源的字符串列表(每行 1 个)。这可能看起来像

foo
bar
goo

目标是仅从模式文件中提取包含两个字符串的行。
重复是可以的(例如 foo foo 是有效的)。

所以这里期望的输出是

foo bar

我设法使用 grep 从模式文件中提取至少包含一个术语的行:

grep -wFf pattern.txt source.txt

上面的命令将返回 source.txt 中的所有行,因为每一行中至少存在 pattern.txt 中的一个术语。我使用管道 grep 命令(在仅考虑两个搜索词的相关问题中显示)的方法尚未成功。

grep 不是强制性的。 awksedperl 也可以工作。我有一个 Python 解决方案,但它非常慢(“极快”)。

谢谢!

对答案的回应

我的 Python 解决方案如下所示:

import sys

f_pattern = sys.argv[1]
f_source = sys.argv[2]

with open(f_pattern, "r", encoding="utf-8") as fp:
    pattern = set(fp.read().split("\n"))

with open(f_source, "r", encoding="utf-8") as fp:
    for line in fp:
        w1, w2 = line.strip("\n").split(" ")
        if w1 in pattern and w2 in pattern:
            print(line, end="")  # \n still present in line string

事实上,与某些答案相比,这并没有那么糟糕(从时间角度来看)。
(我的)Python

time python matcher.py pattern.txt source.txt 
>> 158,12s user 1,82s system 99% cpu 2:40,08 total

awk,作者:@Avinash Chandravansi

time awk -F' ' 'FNR==NR {arr [$0];next} $2 in arr' pattern.txt source.txt
>> 106,72s user 5,69s system 99% cpu 1:52,88 total

还不太确定,但我认为这给出了错误的结果。

awk,作者:@KamilCuk

time awk 'NR==FNR{a[$0];next} {cnt=0; for (k in a) { cnt += $0~k; if (cnt >= 2){ print; break; }}}' pattern.txt source.txt
>> Unclear, more then 20 minutes. Ctrl+C

awk,作者:@Fravadona

time awk 'FNR==NR {patterns[$0]; next}($1 in patterns) && ($2 in patterns)' pattern.txt source.txt
>> 95,45s user 2,46s system 99% cpu 1:38,03 total

^-- 这似乎是公认的答案(对我来说)。

最佳答案

您正在使用 grep -F 所以我猜“模式”不是正则表达式。现在,如果您正在寻找匹配完整字符串(而不是子字符串),那么您可以执行以下操作:

awk '
    FNR == NR { patterns[$0]; next }
    ($1 in patterns) && ($2 in patterns)
' pattern.txt source.txt

关于unix - 包含另一个文件中的两个字符串的匹配行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75464230/

相关文章:

python - 如何设置Python脚本的运行时间

unix - 联机帮助页中的 PROGNAME(x) 引用 -- ()s 中的数字是什么意思?

linux - Bash AWK 找到多个模式并分配给不同的变量

linux - grep 和egrep 选择数字

bash - 搜索文件,显示匹配项和第一行

linux - 根据找到第一个模式找到一个模式并打印行 sed, awk grep

linux - 在/var 目录中查找 catalina.out 文件的 unix 命令是什么?

java - Windows 上的 Marshaller 在文件末尾添加新行

linux - 字符串定界符正在影响其单个字符的某些实例

html - 使用 sed 或 grep 提取 HTML 标签之间的文本