awk或perl解析文本

awk或perl解析文本,awk,Awk,我将awk(也尝试了sed)作为bash菜单的一部分,但它只是立即打开和关闭。我知道我做错了什么,但不知道是什么。谢谢:) 使用正则表达式提取所需的位怎么样 #!/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 aft

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


使用正则表达式提取所需的位怎么样

#!/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
#/usr/perl/bin
严格使用;
使用警告;
而(){
#如果不以NC_0000开头,则跳到下一行
下一个,除非m/^NC_0000/;
#NC\0000后的提取数字
我的($NC_num)=(m/NC_0000(\d+/);
#在“g”之后提取一个或多个数字
我的($g_num)=(m/g\(\d+)/);
#从“>”的任意一侧提取一个字母
我的(@letters)=(m/\d(\w)\>(\w)/);
打印联接(“\t”,$NC\u num,$g\u num,$g\u num,@letters,),“\n”;
}
__资料__
NC_000013.10:g.20763477C>g
NC_00001.10:g.20763477C>g

Perl和awk都是非常有能力的文本解析器。就个人而言,我与perl相处得更好。但这更多的是意见问题

使用正则表达式提取所需的位怎么样

#!/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
#/usr/perl/bin
严格使用;
使用警告;
而(){
#如果不以NC_0000开头,则跳到下一行
下一个,除非m/^NC_0000/;
#提取NC_0000后面的数字
我的($NC_num)=(m/NC_0000(\d+/);
#在“g”之后提取一个或多个数字
我的($g_num)=(m/g\(\d+)/);
#从“>”的任意一侧提取一个字母
我的(@letters)=(m/\d(\w)\>(\w)/);
打印联接(“\t”,$NC\u num,$g\u num,$g\u num,@letters,),“\n”;
}
__资料__
NC_000013.10:g.20763477C>g
NC_00001.10:g.20763477C>g

Perl和awk都是非常有能力的文本解析器。就个人而言,我与perl相处得更好。但这更多的是意见问题

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

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

您对工具的选择应基于您将来维护的方便性。如果你能更好地调试awk,那么就使用awk,因为修复坏掉的东西比稍微不雅观的代码或奇怪的CPU浪费周期要昂贵得多

如果你在找本地人,那么见鬼,你可以用sed来做。我喜欢sed,因为它很短。如果您的后脑中已经安装了正则表达式解析器,那么调试通常也是最有效的。:)


(我正在使用一个变量来插入选项卡,这更明显,但您当然可以将它们添加到行内。)

您选择的工具应该基于您将来的维护方便性。如果你能更好地调试awk,那么就使用awk,因为修复坏掉的东西比稍微不雅观的代码或奇怪的CPU浪费周期要昂贵得多

如果你在找本地人,那么见鬼,你可以用sed来做。我喜欢sed,因为它很短。如果您的后脑中已经安装了正则表达式解析器,那么调试通常也是最有效的。:)



(我使用了一个变量来插入选项卡,这更明显,但您当然可以将它们内联添加。)

这看起来很合理,只是awk中的
-f
选项意味着awk脚本的文件名。您的“内联”awk脚本应该用单引号字符包围,即
awk'FNR>1{……..}'OFS='\t'…
(注意,您不需要
-f
)。您是否遇到错误,或者重新格式化是否正常?如果是这样的话,你应该在问题的主体中包含这些信息。使用编辑框左上角的
{}
工具格式化代码、错误消息和示例数据/输出。祝你好运。警告一句:如果你碰巧有“NC_000123”或其他可能性(即,不总是4开头的“0”),你不会处理这些行。请不要完全替换你现有的问题。如果有更新,可以将其添加到末尾,但如果是新问题,请将其作为单独的问题提问。对于更好的解析备选方案,您有何建议?谢谢:)这看起来很合理,除了awk中的
-f
选项意味着awk脚本的文件名。您的“内联”awk脚本应该用单引号字符包围,即
awk'FNR>1{……..}'OFS='\t'…
(注意,您不需要
-f
)。您是否遇到错误,或者重新格式化是否正常?如果是这样的话,你应该在问题的主体中包含这些信息。使用编辑框左上角的
{}
工具格式化代码、错误消息和示例数据/输出。祝你好运。警告一句:如果你碰巧有“NC_000123”或其他可能性(即,不总是4开头的“0”),你不会处理这些行。请不要完全替换你现有的问题。如果有更新,可以将其添加到末尾,但如果是新问题,请将其作为单独的问题提问。对于更好的解析备选方案,您有何建议?谢谢:)我修改了代码,无法运行。谢谢大家:)。我将重新发布我的道歉。谢谢大家的帮助:)。您应该更喜欢
printf“%s”$s“
,而不是
printf“$s”
(特别是当
$s
是来自外部输入的任意字符串时);在后者中,
$s
中的任何
%
字符都可以被
printf
解释为转换规范。此外,您可以使用
@musiphil,关于printf,请重新阅读我的答案;你的建议行不通
$s
包含一种格式,因此,如果将换行符作为
%s
格式的数据,则不会展开换行符。关于重定向,只有在shell为bash时才有效。这个问题没有指定一个shell。我的答案将在多个shell中工作,而不仅仅是您使用的shell。我修改了代码,无法让它运行。谢谢大家:)。我将重新发布我的道歉。谢谢大家的帮助:)。您应该更喜欢
printf“%s”$s“
,而不是
printf“$s”
(特别是当
$s
是来自外部输入的任意字符串时);在后者中,
$s
中的任何
%
字符都可以解释为转换