我将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
}
答案 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