Regex 除了图案和接下来的n行之外,我怎样才能对所有的东西进行grep呢?

Regex 除了图案和接下来的n行之外,我怎样才能对所有的东西进行grep呢?,regex,bash,shell,grep,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

我有一个文件:

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

您可以使用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

您可以使用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

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

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

CCCC TCATCATACAT 23612763812 DDDD GCTATCGCATC 23767263723
如果text.dat中的每一行都是唯一的:

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

CCCC TCATCATACAT 23612763812 DDDD GCTATCGCATC 23767263723
正则表达式在反转时是闭合的。这意味着,如果可以使用regexp匹配x,则可以使用regexp匹配除x之外的所有对象

假设AAAA\n | BBBB\n是您的模式,您希望将该模式与接下来的三行匹配。与你的问题相反。请注意\n表示换行符

AAAA\n | BBBB\n[^\n]*\n{3}会得到这个。[^\n]表示“除换行以外的所有内容”。这个表达式可以找到您的模式,再加上三条完整的线。因为grep不支持花括号表示法,所以应该使用egrep


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

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

假设AAAA\n | BBBB\n是您的模式,您希望将该模式与接下来的三行匹配。与你的问题相反。请注意\n表示换行符

AAAA\n | BBBB\n[^\n]*\n{3}会得到这个。[^\n]表示“除换行以外的所有内容”。这个表达式可以找到您的模式,再加上三条完整的线。因为grep不支持花括号表示法,所以应该使用egrep

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

如果:

文件中没有选项卡,并且

模式中没有正则表达式元字符,则:

paste -sd'\t\t\n' text.dat |
grep -v -f <(mapfile -t a <names.dat;printf '^%s\t\n' "${a[@]}") |
tr \\t \\n
它的优点是,如果需要的话,可以将三行一组进行比较。

如果:

文件中没有选项卡,并且

模式中没有正则表达式元字符,则:

paste -sd'\t\t\n' text.dat |
grep -v -f <(mapfile -t a <names.dat;printf '^%s\t\n' "${a[@]}") |
tr \\t \\n
它的优点是,如果需要的话,它可以将行分成三组进行比较。

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

输出如下

CCCC
TCATCATACAT
23612763812
DDDD
GCTATCGCATC
23767263723
备注: text.dat在AAAA和BBBB之间以及BBBB和CCCC之间必须有2行,因为2是幻数…

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

输出如下

CCCC
TCATCATACAT
23612763812
DDDD
GCTATCGCATC
23767263723
备注:
text.dat在AAAA和BBBB之间必须有2行,BBBB和CCCC之间也必须有2行,因为2是一个神奇的数字…

。还值得一提的是,如果名称是固定的,您可以使用-F和/或-x来匹配固定字符串,而不是正则表达式,并且只匹配整行。我同意您的看法。非常感谢。我已经更新了我的答案,以避免匹配子字符串。我添加了grep-v“^-”,因为这个问题/问题:如果CCCC下面的一行与AAAA下面的一行相同怎么办?@lihao:请看我第一句话中的限制。我很想走类似的路线。还值得一提的是,如果名称是固定的,您可以使用-F和/或-x来匹配固定字符串,而不是正则表达式,并且只匹配整行。我同意您的看法。非常感谢。我已经更新了我的答案,以避免匹配子字符串。我添加了grep-v“^-”,因为这个问题/问题:如果CCCC下面的一行与AAAA下面的一行相同怎么办?@lihao:请参见我第一句中的限制。你应该试试;您将发现几个问题:1除非您在Gnu grep中指定-E或-P,否则,{不是特别的。2您的意思肯定是[^\n]*;如前所述,该模式将只匹配以下只有一个字符的行,除了3个grep匹配行,而不是任意文本。因此,您永远无法匹配模式中的换行符。逻辑是无可挑剔的,但工具不会配合。使用grep,您无法匹配跨越多行的模式。实际上,您可以使用gnu gre进行匹配p、 但是它涉及到使用-zo并在模式中包含一个文字换行符或使用-p。然后您需要手动进行反转,beca
使用:不再有多行。你应该试试看;您将发现几个问题:1除非您在Gnu grep中指定-E或-P,否则,{不是特别的。2您的意思肯定是[^\n]*;如前所述,该模式将只匹配以下只有一个字符的行,除了3个grep匹配行,而不是任意文本。因此,您永远无法匹配模式中的换行符。逻辑是无可挑剔的,但工具不会配合。使用grep,您无法匹配跨越多行的模式。实际上,您可以使用gnu gre进行匹配p、 但是它需要使用-zo并在模式中包含一个文字换行符,或者使用-p。然后您需要手动进行反转,因为不再有多行。