如何循环遍历文件并使每一行成为 awk 语句中的新正则表达式?

如何循环遍历文件并使每一行成为 awk 语句中的新正则表达式?

文件A.txt:

ATGCATGC 
GGGGGGTT
TTTTT
AAAA

文件B.txt:

asdfasdf
blah2
ATGCATGC
blah3
blah4 
delte-me-too
GGGGGGTT
blah5
blah5
....

我想比较 FileA.txt 中的每一行并检查它是否在 FileB.txt 中。如果是在FileB中,我想删除以下内容:

  1. 匹配线

  2. 上面一行

  3. 下面两行

并输出到一个新文件中。

注意:FileA 中有 500,000 行。我想以一种不对模式进行硬编码的方式来做到这一点。

我目前有一些东西可以删除这些行,但是我对循环 FileA 来为此 awk 表达式创建新模式感到困惑:

awk '/$VARIABLE_REGEX/{for(x=NR-2;x<=NR+2;x++)d[x];} {a[NR]=$0}
END{for(i=1;i<=NR;i++)
    if(!(i in d))
        print a[i]}' FileB.txt

答案1

注意:没有错误检查。另外,假设第二个文件中的输入完全遵循提到的模式。

awk 'NR== FNR {a[$0] = $0 ; next } {if (!($0 in a)) {b[count++] = $0; } else {count--; if (count > 0) delete b[count];getline;getline; }} END {for (i=0; i<count; i++) print b[i] }' 1 2

输入在 1 和 2 中

1

ATGCATGC
GGGGGGTT
TTTTT
AAAA

2

asdfasdf
blah2
ATGCATGC
blah3
blah4 
delte-me-too
GGGGGGTT
blah5
blah5
foo
foo-delete
AAAA
bar-delete
bar-delete
bar-ok

输出

asdfasdf
foo
bar-ok

答案2

下一个代码不是最佳的(因为它必须读取文件B.txt两次)但希望能更快awk

comm --nocheck-order -23 FileB.txt <(grep -B1 -A2 -Ff FileA.txt FileB.txt)

与新GNU sed您可以尝试的命令e(为了节省内存)sed+grep:

sed 'N;h;s/.*\n//;s/.*/grep -xF "&" FileA.txt/e;/./{N;N;d};x;P;D' FileB.txt

答案3

这适用于您的样本

awk '
    NR==FNR {patt[$0]; next} 
    $0 in patt {getline; getline; getline; prev=$0; next} 
    {print prev; prev=$0} 
    END {print prev}
' fileA.txt fileB.txt 

你必须将文件 A 的所有内容保存在内存中,但你只需要一次记住文件 B 中的一行

相关内容