从 file1 读取模式并在 file2 中迭代搜索它们

从 file1 读取模式并在 file2 中迭代搜索它们

我想从 file1 读取模式并在 file2 中迭代搜索它们,打印匹配的行加上 3 行,然后将它们打印到 file3。

现在我正在做:

cat file1 | while read line; do awk '/$line/ {for(i=1; i<=3; i++) {getline; print}}' file2 > file3 ; done

有没有更有效的方法来做到这一点?我的 irl 文件很大(~30GB)

答案1

您可以为每个模式扫描一次文件。仅浏览一次文件会快得多,特别是因为文件不适合缓存。

您的示例代码实际上只保存file1.我认为这过于简单化了。如果您需要单个文件中的所有匹配项,那么就好像这些模式是用“或”运算符连接在一起的。

awk '
    BEGIN {
        while (getline <"file1") pattern = pattern "|" $0;
        pattern = substr(pattern, 2);
    }
    match($0, pattern) {for(i=1; i<=3; i++) {getline; print}}
' file2 > file3

另请注意,这不会打印匹配的行,只会打印以下三行。如果您确实想在以下三行之前打印匹配的行,则需要在循环print;之前添加一个附加内容for

如果您实际上想在以下三行之前打印匹配的行,并且您的grep命令支持该-A参数,那么您应该使用它。像 grep 这样的专门程序通常比 awk 这样的解释性语言更快。作为额外的好处,该命令要简单得多。

grep -A -E -f file1 file2 >file3

如果您发现 grep 速度较慢,可能是因为您在多字节语言环境中遇到了 GNU grep 的缺陷:有时它可能非常慢,即使文件和模式都不包含多字节字符。如果您不使用字符类来匹配非 ASCII 字符(例如,您不使用字符类[[:alpha:]]来匹配所有 Unicode 字母),则在单字节语言环境中运行 grep:

LC_ALL=C grep -A3 -E -f file1 file2 >file3

grep 的输出与 awk 片段并不完全相同,因为如果由于前一行而在正在打印的其中一行中找到该模式,则它们的行为会有所不同。例如,如果模式是a并且行是a1, a2, b, cdgrep -A3打印a1, a2, bc而上面的 awk 片段打印a2, bc并且带有附加print打印的 awk 片段打印a1, a2, b, c

相关内容