我有一个 ID 和数字(位置)的排序文件。我需要将第二列中的位置分组为 500 的间隔,然后分成不同的文件。
输入
snp00001 200
snp00002 300
snp00003 400
snp00004 500
snp00005 600
snp00006 900
snp00007 1500
snp00008 1800
snp00009 3000
snp00010 3500
snp00011 4000
snp00012 5000
所需输出
snp00001 200 Group1
snp00002 300 Group1
snp00003 400 Group1
snp00004 500 Group1
snp00005 600 Group1
snp00006 900 Group2
snp00007 1500 Group3
snp00008 1800 Group3
snp00009 3000 Group4
snp00010 3500 Group4
snp00011 4000 Group5
snp00012 5000 Group6
然后将这些组保存到不同的文件中,分别重命名为Group1
、Group2
和。Group3
Group4
我尝试过bedtools
其他一些命令,但问题无法解决。
任何帮助将不胜感激。
谢谢你!
答案1
这是一份完美的工作awk
:
$ awk -v step=500 -v OFS='\t' \
'{
if(NR==1 || $2>limit){
limit=$2+step
group++
}
file="Group"group; print $0,file
}' input_file
snp00001 200 Group1
snp00002 300 Group1
snp00003 400 Group1
snp00004 500 Group1
snp00005 600 Group1
snp00006 900 Group2
snp00007 1500 Group3
snp00008 1800 Group3
snp00009 3000 Group4
snp00010 3500 Group4
snp00011 4000 Group5
snp00012 5000 Group6
要打印到单独的文件中,请执行以下操作:
awk -v step=500 -v OFS='\t' \
'{
if(NR==1 || $2>limit){
limit=$2+step
group++
}
file="Group"group; print $0,file > file
}' input_file
Group1
这将从您的示例数据生成文件Group5
,格式如下:
$ cat Group1
snp00001 200 Group1
snp00002 300 Group1
snp00003 400 Group1
snp00004 500 Group1
snp00005 600 Group1
$ cat Group6
snp00012 5000 Group6
答案2
使用 Perl + csplit。范围运算符或触发器运算符“...”
perl \
-lMconstant='LIM,500' \
-sane \
'
my $e = do{$a=$F[1];1;} ... $F[1]-$a>LIM;
print(qq($_\tGroup$k)),next
if $e !~ /E0/ || $eof;
print(q());$k++;
redo if !eof || !$eof++;
' -- -k=1 file |
csplit --suppress-matched \
-sz -f 'Group' - '/^$/' '{*}'