Bash awk条件在循环中始终为真
早上好 很抱歉,这个问题对一些人来说似乎微不足道。这几个小时来一直让我发疯。我的问题如下: 我有两个文件:Bash awk条件在循环中始终为真,bash,awk,while-loop,perl,Bash,Awk,While Loop,Perl,早上好 很抱歉,这个问题对一些人来说似乎微不足道。这几个小时来一直让我发疯。我的问题如下: 我有两个文件: head <input file> SNP CHR BP A1 A2 OR P chr1:751343 1 751343 A T 0.85 0.01 chr1:751756 1 751756 T C 1.17 0.01 rs3094315 1 752566 A G 1.14 0.0093 rs3131972 1 752721 A G 0.88 0.009 rs3131971 1
head <input file>
SNP CHR BP A1 A2 OR P
chr1:751343 1 751343 A T 0.85 0.01
chr1:751756 1 751756 T C 1.17 0.01
rs3094315 1 752566 A G 1.14 0.0093
rs3131972 1 752721 A G 0.88 0.009
rs3131971 1 752894 T C 0.87 0.01
chr1:753405 1 753405 A C 1.17 0.01
chr1:753425 1 753425 T C 0.87 0.0097
rs2073814 1 753474 G C 1.14 0.009
rs2073813 1 753541 A G 0.85 0.0095
头部
SNP CHR BP A1 A2或P
chr1:751343 1 751343 A T 0.85 0.01
chr1:751756 1 751756 T C 1.17 0.01
rs3094315 1752566 A G 1.14 0.0093
rs3131972 1 752721 A G 0.88 0.009
rs3131971 752894 T C 0.87 0.01
chr1:753405 1 753405 A C 1.17 0.01
chr1:753425 1 753425 T C 0.87 0.0097
rs2073814 1 753474 G C 1.14 0.009
rs2073813 1 753541 A G 0.85 0.0095
及
头部
1 112667912 114334946
1 116220516 117220516
1 160997252 161997252
1 198231312 199231314
2 60408994 61408994
2 64868452 65868452
2 99649474 100719272
2 190599907 191599907
2 203245673 204245673
2 203374196 204374196
我想使用bash脚本删除输入文件中的所有行,其中BP列位于输入文件中指定的间隔内,并且CHR列与间隔文件的第一列匹配
以下是我一直在使用的代码(尽管欢迎使用更简单的解决方案):
读取间隔;做
chr=$(echo$interval | awk'{print$1}')
开始=$(echo$interval | awk'{print$2}')
停止=$(echo$interval | awk'{print$3}')
啊!2美元=$chr{print}$2==$chr&&($3$STOP){print}'tmp
mv tmp
完成<
我的问题是没有从输入文件中删除任何行。即使命令
awk '$2==1 && ($3>112667912 && $3<114334946) {print}' < input_file | wc -l
awk'$2==1&&($3>112667912&&$3您可以尝试使用代替。原因是在中,您可以创建数组散列以保存interval
文件的数据,并在处理输入时更容易提取,如:
perl -lane '
$. == 1 && next;
@F == 3 && do {
push @{$h{$F[0]}}, [@F[1..2]];
next;
};
@F == 7 && do {
$ok = 1;
if (exists $h{$F[1]}) {
for (@{$h{$F[1]}}) {
if ($F[2] > $_->[0] and $F[2] < $_->[1]) {
$ok = 0;
last;
}
}
}
printf qq|%s\n|, $_ if $ok;
};
' interval input
因此,您可以运行它并获得结果:
SNP CHR BP A1 A2 OR P
chr1:751343 1 751343 A T 0.85 0.01
rs3094315 1 752566 A G 1.14 0.0093
rs3131972 1 752721 A G 0.88 0.009
rs3131971 1 752894 T C 0.87 0.01
chr1:753405 2 753405 A C 1.17 0.01
chr1:753425 1 753425 T C 0.87 0.0097
我想你在awk
中做这一切会更快更容易,尽管我无法从你的描述中看出你想做什么。看看我在这里的回答,看看如何用awk
阅读2个文件,谢谢@TomFenech。我试过awk-v start=“$start”-v stop=“$stop”$2!=$chr{print}$2==$chr&($3stop){print}“tmp
但没有成功。请您进一步解释我可能如何实现您的解决方案。@MarkSetchell,我非常想用awk来完成整个过程。为了澄清我的描述,如果CHR字段与间隔文件的$1匹配,并且BP列中的数字介于间隔文件的$2和$3中的数字(不一定与数字完全匹配),您需要以相同的方式传递$chr
:)当然。。。我很抱歉。这很有魅力。谢谢你的帮助这很有效。然而,由于我缺乏使用pearl的经验,我想我会选择在对我的问题的评论中建议的解决方案。我接受这个答案,因为另一个解决方案只是作为评论发布的。
perl -lane '
$. == 1 && next;
@F == 3 && do {
push @{$h{$F[0]}}, [@F[1..2]];
next;
};
@F == 7 && do {
$ok = 1;
if (exists $h{$F[1]}) {
for (@{$h{$F[1]}}) {
if ($F[2] > $_->[0] and $F[2] < $_->[1]) {
$ok = 0;
last;
}
}
}
printf qq|%s\n|, $_ if $ok;
};
' interval input
SNP CHR BP A1 A2 OR P
chr1:751343 1 751343 A T 0.85 0.01
chr1:751756 1 112667922 T C 1.17 0.01
rs3094315 1 752566 A G 1.14 0.0093
rs3131972 1 752721 A G 0.88 0.009
rs3131971 1 752894 T C 0.87 0.01
chr1:753405 2 753405 A C 1.17 0.01
chr1:753425 1 753425 T C 0.87 0.0097
rs2073814 1 199231312 G C 1.14 0.009
rs2073813 2 204245670 A G 0.85 0.0095
SNP CHR BP A1 A2 OR P
chr1:751343 1 751343 A T 0.85 0.01
rs3094315 1 752566 A G 1.14 0.0093
rs3131972 1 752721 A G 0.88 0.009
rs3131971 1 752894 T C 0.87 0.01
chr1:753405 2 753405 A C 1.17 0.01
chr1:753425 1 753425 T C 0.87 0.0097