sed:删除与给定字段中的模式匹配的行
sed: delete lines that match a pattern in a given field
我有一个分隔的文件制表符,如下所示:
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
53_234 78 . CCG GAT 999 . . GT:PL:DP:DPR
45_569 5 . TCCG GTTA 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR
我正在尝试使用 sed 删除在第 4 个字段中包含一个以上字母的所有行(在上面的例子中,从顶部开始的第 7 行和第 8 行)。我已经尝试了以下正则表达式,但一定有一些我找不到的小故障:
sed '5,${;/\([^.]*\t\)\{3\}\[A-Z][A-Z]\+\t/d;}' input.vcf>new.vcf
语法如下:
- 5,$ #从第 5 行开始直到文件结尾 ($)
- ([^.]*\t) #匹配组是任意单个字符后跟零个或多个字符后跟制表符。
- {3} #previous 块重复 3 次(大概是第 4 个字段)
- [A-Z][A-Z]+\t #后跟两个或更多字母的任意字符串,后跟制表符。
不幸的是,这不起作用,但我知道我快要让它起作用了。任何提示或帮助都会使这成为一个伟大的教学时刻。
谢谢
如果 awk
适合您,您可以使用以下命令:
awk '(FNR<5){print} (FNR>=5)&&length()<=1' input.vcf
默认分隔符是space
,可以用-F"\t"切换成制表符,放在awk
之后。例如,awk -F"\t" ....
(FNR<5){print}
FNR为文件编号记录,小于5时打印整行
(FNR>=5) && length()<=1
将处理其余行和过滤行,其中第 4 个字段不超过一个字符。
输出:
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR
您可以将输出重定向到输出文件。
修复了你的 sed 过滤器(我花了一段时间差点被它弄疯了)
5,${/^\([^\t]\+\t\)\{3\}[A-Z][A-Z]\+\t/d}
你的错误:
[^.]*: everything but a dot.
感谢 Ed,现在我知道了。我认为点必须被转义,但这似乎不适用于括号之间。无论如何,这可以匹配一个制表字符并匹配 2 或 3 个组而不是一个,无法匹配您的行(默认情况下正则表达式是贪婪的)
\[A-Z][A-Z]: bad backslash. What did it do? hum, dunno!
测试:
$ sed '5,${/^\([^\t]\+\t\)\{3\}[A-Z][A-Z]\+\t/d}' foo.Txt
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR
结论:要处理分隔字段,awk
更好:)
$ awk 'NR<5 || ~/^.$/' file
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR
我有一个分隔的文件制表符,如下所示:
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
53_234 78 . CCG GAT 999 . . GT:PL:DP:DPR
45_569 5 . TCCG GTTA 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR
我正在尝试使用 sed 删除在第 4 个字段中包含一个以上字母的所有行(在上面的例子中,从顶部开始的第 7 行和第 8 行)。我已经尝试了以下正则表达式,但一定有一些我找不到的小故障:
sed '5,${;/\([^.]*\t\)\{3\}\[A-Z][A-Z]\+\t/d;}' input.vcf>new.vcf
语法如下:
- 5,$ #从第 5 行开始直到文件结尾 ($)
- ([^.]*\t) #匹配组是任意单个字符后跟零个或多个字符后跟制表符。
- {3} #previous 块重复 3 次(大概是第 4 个字段)
- [A-Z][A-Z]+\t #后跟两个或更多字母的任意字符串,后跟制表符。
不幸的是,这不起作用,但我知道我快要让它起作用了。任何提示或帮助都会使这成为一个伟大的教学时刻。 谢谢
如果 awk
适合您,您可以使用以下命令:
awk '(FNR<5){print} (FNR>=5)&&length()<=1' input.vcf
默认分隔符是space
,可以用-F"\t"切换成制表符,放在awk
之后。例如,awk -F"\t" ....
(FNR<5){print}
FNR为文件编号记录,小于5时打印整行
(FNR>=5) && length()<=1
将处理其余行和过滤行,其中第 4 个字段不超过一个字符。
输出:
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR
您可以将输出重定向到输出文件。
修复了你的 sed 过滤器(我花了一段时间差点被它弄疯了)
5,${/^\([^\t]\+\t\)\{3\}[A-Z][A-Z]\+\t/d}
你的错误:
[^.]*: everything but a dot.
感谢 Ed,现在我知道了。我认为点必须被转义,但这似乎不适用于括号之间。无论如何,这可以匹配一个制表字符并匹配 2 或 3 个组而不是一个,无法匹配您的行(默认情况下正则表达式是贪婪的)
\[A-Z][A-Z]: bad backslash. What did it do? hum, dunno!
测试:
$ sed '5,${/^\([^\t]\+\t\)\{3\}[A-Z][A-Z]\+\t/d}' foo.Txt
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR
结论:要处理分隔字段,awk
更好:)
$ awk 'NR<5 || ~/^.$/' file
##INFO=<ID=AC1,Number=1,Type=Float,Description="Max-likelihood">
##INFO=<ID=MQ,Number=1,Type=Integer,Description="Root-mean-square">
##INFO=<ID=FQ,Number=1,Type=Float,Description="Phred probability">
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT
53_344 2 . C G 999 . . GT:PL:DP:DPR
6_56775 67 . T A 999 . . GT:PL:DP:DPR
3_67687 2 . T G 999 . . GT:PL:DP:DPR
53_569 89 . T G 999 . . GT:PL:DP:DPR