如何在特定条件下从文件中提取行

如何在特定条件下从文件中提取行

文件:

chromosome  position  ref  alt 
chr1          1398     A    T 
chr1          2980     A    C 
chr2          3323     C    T,A
chr2          3749     T    G
chr3          5251     C    T,G
chr3          9990     G    C,T
chr4          10345    T    G 

当第 4 列有 2 个或更多由逗号分隔的字符时,我需要提取整行

预期输出为:

chr2          3323     C    T,A
chr3          5251     C    T,G
chr3          9990     G    C,T 

答案1

还有其他几种看待这个问题的方法。

方法#1

由于您只对包含超过 2 个以逗号分隔的字符的行感兴趣,因此您可以只grep对逗号进行操作:

$ grep "," sample.txt 
chr2          3323     C    T,A
chr3          5251     C    T,G
chr3          9990     G    C,T

方法#2

您可以使用 的grepPCRE 工具。这里grep可以使用Perl的正则表达式引擎来进行匹配。它非常强大,可以让您完成许多使用 Perl 可以做的事情grep

松散定义

$ grep -P "(\w,)+" sample.txt 

严格定义

$ grep -P '\w+\d\s+\d+\s+\w\s+(\w,)+' sample.txt 

方法#3

使用awk。这再次利用了这样一个事实:只有带逗号 ( ,) 的行才有意义,因此它只是找到它们并打印它们:

松散定义

$ awk '/,/{print}' sample.txt 

更严格的定义

$ awk '/([[:alpha:]])+,[[:alpha:]]/{print}' sample.txt 

甚至更严格的定义

$ awk '$4 ~ /([[:alpha:]])+,[[:alpha:]]/{print}' sample.txt

该命令查看第四列的内容,并检查它是否是一个字母,后跟一个逗号,然后是另一个字母。

甚至更严格的定义

$ awk '$4 ~ /([GATC])+,[GATC]/{print}' sample.txt 

这仅查找 G、A、T 或 C,后跟逗号,后跟另一个 G、A、T 或 C。

答案2

perl -ane 'print if($F[3] =~ /^\w,\w/$);' file

-n告诉 perl 一次一行地处理 infile,将每一行传递给 中指定的命令-e。告诉-aperl 展开字段分隔符周围的每一行(默认为空格),并将其分配给一个名为 的数组@F。结果是我们可以处理每一行并使用它$F[n]来引用该行的第 n 个元素。

然后,我们测试字段 4 是否$F[3]包含 string 的开头^、一个单词字符\w,后跟一个逗号,然后是另一个单词字符\w,然后是 string 的结尾$。如果成功了,我们就print下线了。

如果这些“单词字符”始​​终是胞嘧啶、腺嘌呤、鸟嘌呤和胸腺嘧啶,您可以使用以下命令使其更明确:

perl -ane 'print if($F[3] =~ /^[GATC],[GATC]$/);' file

答案3

另一个 awk 解决方案。

awk 'length($4) > 2 && $4 ~ /^([^,],)+[^,]$/' file_name

使用 nawk 进行测试,也可以与 gawk 一起使用。这将匹配 A、T、G、C、Z、Q、R

同样,如果您只是匹配 ATGC:

awk 'length($4) > 2 && $4 ~ /([ATGC],)+[ATGC]/' file_name

答案4

简单的awk一句:

awk '$4 ~ ","' file

相关内容