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' - '/^$/' '{*}'