使用awk或gawk提取字符串的一部分

时间:2014-06-25 14:38:24

标签: awk

我有一个这样的文件:

HMIC_insuff/out/expected_dcct_1kg_only10_1.res:---      rs4142674       4301956 T       C       0.950073        0.740579        0.895093        0.299186        0.628359        1.27505 1304    563     741     +       0.537017        0.553135        0

HMIC_insuff/out/expected_dcct_1kg_only11_16.res:rs10899221      rs10899221      76181631        A       G       0.0778374       0.414726        1.14734 0.189249        0.860697        1.52945 1304    563     741     +       1       0.848675        0

HMIC_insuff/out/expected_dcct_1kg_only11_17.res:---     rs61900305      82984402        A       C       0.125867        0.893738        1.06007 0.148316        0.839765        1.33818 1304    563     741     +       0.997527        0.705928        0

我试图从每个字符串HMIC_insuff / out / expected_dcct_1kg_only11_17.res中获取第一列中的数字“11”或“10”:---(因为您看到11正好在字符串后面“ “或者10是字符串后面的”只有“),我正在尝试多步awk,将-F定义为_only并获取第二个字段,然后重复使用不同的-F来隔离数字”11“或”10“从第一列开始。但不知何故,即使经过几次awk步骤我也无法做到,因为我还需要摆脱附加在“11”或“10”上的部分,例如“_17.res ---”或“_16”部分.RES:rs10899221"

我相信这可以使用gawk中的表达式来解决,但我对它很新,所以我不知道如何解决这个问题。

此外,我希望我的最终表看起来像这样(所以基本上只是同一个表,但第一列只包含“_only”之后的数字):

11      rs10899221      76181631        A       G       0.0778374       0.414726        1.14734 0.189249        0.860697        1.52945 1304    563     741     +       1       0.848675        0

11   rs61900305      82984402        A       C       0.125867        0.893738        1.06007 0.148316        0.839765        1.33818 1304    563     741     +       0.997527        0.705928        0

谢谢

1 个答案:

答案 0 :(得分:1)

使用sed,因为它快速而简单:

sed 's/^[^:]*only\(1[01]\)[^ ]*/\1/'

请注意,这会打印出不匹配的行(没有'只有10'或者只有'只有11')。如果你想要那些省略,那么你使用:

sed -n '/^[^:]*only\(1[01]\)[^ ]*/ s//\1/p'

我不会使用awk来做这件事;如果sed不合适,我会选择Perl。


如果只有'之后的数字?可以是一个或两个数字,那么你需要使用一个适当的正则表达式而不是显示的那个,这是经过精心设计的,因此它只能在问题中提取10和11(可能后跟其他数字)。在提出问题时要小心,以区分适用于特定样本数据的内容和适用于一般情况的内容。询问一般情况,然后描述它如何应用于特定的样本数据。

这是一个可能符合您澄清要求的变体。

sed -n '/^[^:]*only\([0-9]\{1,2\}\)_[^ ]*/ s//\1/p'

正则表达式查找行的开头,一系列非冒号后跟“仅”,然后是一个或两个数字(记住),下划线,可能还有一些非空格。对于那些匹配的行,整个模式被记住的一个或两个数字替换,然后打印行的左边。如果有三位数字,则不会打印该行。如果您不在乎多少位数,则可以使用\([0-9][0-9]*\)代替。您可以将[^ ]替换为[^:],而不会产生任何伤害。

我使用严谨的经典sed符号来编写,因为它可以在任何地方使用。某些版本的sed支持更接近PCRE - 就像正则表达式一样。我并不经常使用它们,因为它们不便携,即使它们使用PCRE也使用的一些符号,它们也不一定是PCRE。