删除行,如果file1中的列属于其他文件中的两列中声明的范围内

我一直在这个问题上工作了一段时间,令人惊讶的是没有发现很多帮助search。 我有两个制表符分隔的文件,看起来像这样:

文件1

#CHROM POS ..~100 columns... ref|NC_001133| 250... ref|NC_001133| 500... ref|NC_001133| 802... ref|NC_001133| 15052... ref|NC_001133| 23560... ref|NC_001133| 28800... 

另一个看起来像这样:

文件2

 #CHROM POS1 POS2 ref|NC_001133| 1 801 ref|NC_001133| 1 62 ref|NC_001133| 337 801 ref|NC_001133| 63 336 ref|NC_001133| 1807 2169 ref|NC_001133| 13363 13743 ref|NC_001133| 24000 27968 

我想要的是删除file1中的行在POS1和POS2指定的范围内的行。 所以我的预期产出将是:

预期产出:

 #CHROM POS ..~100 columns... ref|NC_001133| 802... ref|NC_001133| 15052... ref|NC_001133| 23560... ref|NC_001133| 28800... 

我已经尝试了几个代码,包括这个产生一个没有任何文件的代码:

 awk 'NR==FNR{ range[$1,$2,$3]; next } FNR==1{for(x in range) {split(x, check, SUBSEP); if($1==check[1] && $2>=check[2] && $2<=check[3]) print $0,"\t", "x"}}' todeleteshort.txt short_test.txt > test_short_output.txt 

我试图修改此页面上使用的代码: AWK:如果文件1中的列落入其他文件中的两列中声明的范围内,则提取行

但我没有删除我不想要的行,而保持我想要的行。

只要可以从命令行运行,我不在乎什么语言。

任何帮助将非常感激!

 awk ' NR == 1 {next} # file2 header FNR == 1 {print; next} # file1 header FNR == NR {min[FNR]=$2; max[FNR]=$3; next} { for (key in min) if (min[key] <= $2 && $2 <= max[key]) next print } ' file2 file1 

使用sed来代替,因为删除行包含范围界限,所以它非常容易。

您可以告诉sed执行一系列行的操作,例如sed '10,20d; 25,35d'将执行第10行到第20行的“d”或删除命令,并再次执行第25行到第35行。

请注意,您可以使用换行符而不是; 为每个单独的命令。 这是我们在这里简单的,因为你的file2中的数据已经是基于行的。

所以你所要做的就是将file2中的POS1,POS2列变成上面的命令列表,然后用你创build的命令运行sed。 如果时间很长,可以从file2生成一个sed脚本文件并执行它。 像这样的东西

 # build the command that will be run by sed. typeset sed_cmd=$(sed '1d' file2 | awk '{print $2","$3"d"}') # Now execute the sed command you constructed on file1. sed "$cmd" file1 > results_file # If you want sed to modify the input file1 in place use the -i option. sed -i "$cmd" file1 

awk来拯救!

 $ awk 'FNR==NR && NR>1 {p1[NR]=$2; p2[NR]=$3; count=NR; next} FNR>1{for(i=2;i<=count;i++) if($2>=p1[i] && $2<=p2[i]) next} NR>1' file2 file1 #CHROM POS ..~100 columns... ref|NC_001133| 802 ref|NC_001133| 15052 ref|NC_001133| 23560 ref|NC_001133| 28800