除了模式和接下来的n行之外,我怎样才能获得所有内容?

时间:2014-09-08 20:32:46

标签: regex bash shell grep

我有一个文件:

NAMES.DAT:

AAAA
BBBB

text.dat:

AAAA
CTGCTTCGTCA
12127567612
BBBB
TCGACTACTAG
12331276318
CCCC
TCATCATACAT
23612763812
DDDD
GCTATCGCATC
23767263723

我要做的是(仅使用shell命令)从text.dat中排除这些行,这些行也存在于names.dat中,并且(最重要的是)在公共行之后有三行。

所以基本上输出应该看起来像是:

CCCC
TCATCATACAT
23612763812
DDDD
GCTATCGCATC
23767263723

5 个答案:

答案 0 :(得分:6)

您可以使用awk执行此操作:

awk 'NR==FNR {a[$0]; next} $0 in a {i=0} ++i>3' names.dat text.dat

NR==FNR表示总记录数等于当前文件的记录号(仅对第一个文件为真)。使用names.dat行设置数组a中的键。 next跳到输入的下一行,忽略单行中的任何其他命令。只要text.dat中的一行与a的元素匹配,计数器i就会重置为0.只有在i大于3时才会打印。

测试出来:

$ awk 'NR==FNR {a[$0]; next} $0 in a {i=0} ++i>3' names.dat text.dat 
CCCC
TCATCATACAT
23612763812
DDDD
GCTATCGCATC
23767263723

答案 1 :(得分:3)

如果text.dat中的每一行都是唯一的:

grep -Fxvf <(grep -f names.dat -A 2 text.dat | grep -v '^--' ) text.dat

输出:

CCCC
TCATCATACAT
23612763812
DDDD
GCTATCGCATC
23767263723

答案 2 :(得分:0)

如果:

  1. 文件中没有标签,

  2. 模式中没有正则表达式元字符,然后:

    paste -sd'\t\t\n' text.dat |
    grep -v -f <(mapfile -t a <names.dat;printf '^%s\t\n' "${a[@]}") |
    tr \\t \\n
    
  3. 具有以下优点:它真正比较了三个一组的行,如果这是所期望的。

答案 3 :(得分:0)

您可以使用grep命令执行此操作。

grep -v "`grep -f name.dat -A 2 text.dat`" text.dat

输出低于。

CCCC
TCATCATACAT
23612763812
DDDD
GCTATCGCATC
23767263723

注: text.dat必须在&#34; AAAA&#34;之间有2行。和&#34; BBBB&#34;还&#34; BBBB&#34;和&#34; CCCC&#34;因为&#34; 2&#34;是神奇的数字......

答案 4 :(得分:-1)

正则表达式在反转下关闭。这意味着如果您可以使用正则表达式匹配 x ,则可以使用正则表达式匹配除 x 之外的所有内容。

(AAAA\n|BBBB\n)是你的模式,你想匹配那个模式和接下来的三行。 (与您的问题相反。)请注意\n表示换行符。

(AAAA\n|BBBB\n)([^\n]*\n){3}会得到这个。 [^\n]表示“除换行符之外的所有内容”。此表达式查找您的模式,以及三个完整的行。 (由于grep不支持大括号表示法,因此您应使用egrep。)

传递参数-v以反转表达式。