如果file1中的列落在其他文件

时间:2016-03-28 19:24:31

标签: excel bash awk

我一直在研究这个问题,但令人惊讶的是,搜索并没有找到太多帮助。 我有两个制表符分隔的文件,其中一个看起来像这样:

档案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: extract lines if column in file 1 falls within a range declared in two columns in other file

但是我没有删除我不想要的线条,同时保留了我想要的线条。

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

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:1)

请改用sed,因为删除行包含范围界限,因此非常容易。

你可以告诉sed对一系列行进行动作,例如sed&#39; 10,20d; 25,35d&#39;将执行&#34; d&#34;或删除第10到20行的命令,并再次删除第25到35行。

请注意,您可以使用换行符代替;对于每个单独的命令。这是我们为简单起见的原因,因为file2中的数据已基于行。

所以您需要做的就是将file2中的POS1,POS2列转换为上面的命令列表,然后使用您创建的命令运行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 

答案 1 :(得分: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

答案 2 :(得分:0)

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
相关问题