我有一个文件:
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
答案 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)
如果:
文件中没有标签,
模式中没有正则表达式元字符,然后:
paste -sd'\t\t\n' text.dat |
grep -v -f <(mapfile -t a <names.dat;printf '^%s\t\n' "${a[@]}") |
tr \\t \\n
具有以下优点:它真正比较了三个一组的行,如果这是所期望的。
答案 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
以反转表达式。