awk或perl来解析文本

时间:2015-03-11 17:08:21

标签: awk

我将awk(也尝试使用sed)作为bash菜单的一部分,但它只是立即打开和关闭。我知道我做错了什么但不确定是什么。谢谢你:)。

    convert() {
printf "\n\n"
cd 'C:\Users\cmccabe\Desktop\annovar'
awk 'FNR > 1 && match($0, /NC_0000([0-9]*)\..*g\.([0-9]+)(.)>(.)/, a) { print a[1], a[2], a[2], a[3], a[4] }' OFS='\t' ${id}.txt 
    *) convert ;;
esac
}


 convert() {
 printf "\n\n"
 cd 'C:\Users\cmccabe\Desktop\annovar'
 t=$'\t'
 s='NC_000013.10:g.20763477C>G\nNC_00001.10:g.20763477C>G\n'
 printf "$s" | sed -r -n -e "s/^NC_0{4,}([0-9]+)\.[^.]*\.([0-9]+).*([A-Z])>      ([A-Z]).*/\1$t\2$t\2$t\3$t\4/p"
    *) convert ;;
 esac
}

3 个答案:

答案 0 :(得分:2)

如何使用正则表达式提取所需的位?

#!/usr/perl/bin
use strict;
use warnings;

while (<DATA>) {
    #skip to next row if doesn't start with NC_0000
    next unless m/^NC_0000/; 
    #extract digits after NC_0000
    my ($NC_num)  = (m/NC_0000(\d+)/);
    #extract 1 or more digits after 'g.'
    my ($g_num)   = (m/g\.(\d+)/);
    #extract a single letter, either side of '>' 
    my (@letters) = (m/\d(\w)\>(\w)/);
    print join( "\t", $NC_num, $g_num, $g_num, @letters, ), "\n";
}

__DATA__
NC_000013.10:g.20763477C>G
NC_00001.10:g.20763477C>G

Perl和awk都是功能强大的文本解析器。 个人我与perl相处得更好。但这更多的是意见问题。

答案 1 :(得分:2)

您选择的工具应该基于您将来的易维护性。如果你有更好的时间调试awk,那么使用awk,因为修复破坏的东西比稍微不优雅的代码或奇怪的浪费的CPU周期更昂贵。

如果你正在寻找altnernatives,那么heck,你可以用sed做到这一点。我喜欢sed,因为它是。如果您的后脑中已经安装了正则表达式解析器,那么调试通常也是最有效的。 :)

$ t=$(printf '\t')
$ s='NC_000013.10:g.20763477C>G\nNC_00001.10:g.20763477C>G\n'
$ printf "$s" | sed -r -n -e "s/^NC_0{4,}([0-9]+)\.[^.]*\.([0-9]+).*([A-Z])>([A-Z]).*/\1$t\2$t\2$t\3$t\4/p"
13      20763477        20763477        C       G
1       20763477        20763477        C       G
$

(我使用变量更明显地插入标签,但你当然可以直接添加它们。)

答案 2 :(得分:1)

gawk可以做到:

$ gawk 'FNR > 1 && match($0, /NC_0000([0-9]*)\..*g\.([0-9]+)(.)>(.)/, a)
{ print a[1], a[2], a[2], a[3], a[4] }' OFS='\t' input
13  20763477    20763477    C   G
1   20763477    20763477    C   G