![이전 필드에 일치하는 항목이 있으면 열을 가로로 결합합니다. 조인할 여러 열](https://linux55.com/image/123533/%EC%9D%B4%EC%A0%84%20%ED%95%84%EB%93%9C%EC%97%90%20%EC%9D%BC%EC%B9%98%ED%95%98%EB%8A%94%20%ED%95%AD%EB%AA%A9%EC%9D%B4%20%EC%9E%88%EC%9C%BC%EB%A9%B4%20%EC%97%B4%EC%9D%84%20%EA%B0%80%EB%A1%9C%EB%A1%9C%20%EA%B2%B0%ED%95%A9%ED%95%A9%EB%8B%88%EB%8B%A4.%20%EC%A1%B0%EC%9D%B8%ED%95%A0%20%EC%97%AC%EB%9F%AC%20%EC%97%B4.png)
따라서 다음과 같은 일부 서명 마커(chr, start, end, chr, 별표, end, 겹치는 기본 쌍 수)가 포함된 삽입 히트가 포함된 파일이 있습니다.
chr1 69744110 69793325 . -1 -1 0
chr1 82791976 82831348 chr1 82792114 82792615 501
chr1 82791976 82831348 chr1 82816285 82817077 792
chr1 82791976 82831348 chr1 82828015 82829891 1876
chr1 88599340 88658398 . -1 -1 0
chr1 137772945 137830035 . -1 -1 0
chr1 137875312 137920590 . -1 -1 0
chr1 193433080 193446861 . -1 -1 0
chr10 26483800 26501370 chr10 26484794 26485295 501
chr10 68069913 68089436 . -1 -1 0
chr10 95098349 95113967 . -1 -1 0
chr10 97310211 97335589 . -1 -1 0
chr10 111083097 111118237 chr10 111088928 111090274 1346
chr10 117904141 117947090 chr10 117905334 117906320 986
chr10 117904141 117947090 chr10 117918966 117919852 886
chr10 117904141 117947090 chr10 117926867 117927368 501
chr11 11521339 11587607 chr11 11523970 11524747 777
chr11 11521339 11587607 chr11 11555497 11559868 4371
chr11 11521339 11587607 chr11 11560639 11562128 1489
chr11 11521339 11587607 chr11 11564617 11565370 753
그래서 필요한 것은 5열(column5/column5...), 6열(column6/column6...) 및 7열(column/column7)의 값을 연결하는 것입니다... 제가 첫 번째에 있다면 3열에 일치 항목이 있습니다. 4열도 보관하고 싶은데, 놓쳐도 괜찮습니다.
출력은 다음과 같아야 합니다.
chr1 69744110 69793325 . -1 -1 0
chr1 82791976 82791976 chr1 82792114/82816285/82828015 82792615/82817077/82829891 501/792/1876
chr1 88599340 88658398 . -1 -1 0
chr1 137772945 137830035 . -1 -1 0
chr1 137875312 137920590 . -1 -1 0
chr1 193433080 193446861 . -1 -1 0
chr10 26483800 26501370 chr10 26484794 26485295 501 (...)
chr10 117904141 117947090 chr10 117905334/117918966/117926867 117906320/117919852/117927368 986/886/501
(...)
여러 번 실험해 본 결과 내가 할 수 있는 최선의 방법은 다음과 같습니다.
awk '{ k=$1 FS $2 FS $3; a[k]=(k in a)? a[k]"/"$5 : $5 }
END{ for(i in a) {
split(i,b,FS); b[5]=a[i]"\t"b[5]; r="";
for(j=1;j<=NF;j++) {
r=(r!="")? r"\t"b[j] : b[j]
}
print r}
}' input.bed > output.bed
하지만 이렇게 하면 값이 손실되고 여러 열을 결합할 수 없습니다.
도와주세요?
편집하다:
새로운 시도:
awk -F'\t' -v OFS='\t' '{
if ($2 in a) {
a[$2] = a[$2]";"$5;
b[$2] = b[$2]";"$6;
} else {
a[$2] = $5;
b[$2] = $6;
}
}
END { for (i in a) print i, a[i], b[i] }' input.bed > output.bed
하지만 평가되지 않은 필드가 계속 손실됩니다.
답변1
awk를 사용하세요. 불행하게도 awk에는 배열 연결 기능이 내장되어 있지 않지만 gawk 온라인 매뉴얼에는 배열 연결을 작성하는 방법에 대한 예가 있습니다.
이것이 파일에 있는 경우 aggregate.awk
(입력 파일이 탭으로 구분되어 있다고 가정합니다)
BEGIN {
FS = OFS = "\t"
}
# ref https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html#Join-Function
function join(array, start, end, sep, result, i)
{
if (sep == "")
sep = " "
else if (sep == SUBSEP) # magic value
sep = ""
result = array[start]
for (i = start + 1; i <= end; i++)
result = result sep array[i]
return result
}
function print_record() {
last_line[5] = join(col5, 1, n, "/")
last_line[6] = join(col6, 1, n, "/")
last_line[7] = join(col7, 1, n, "/")
print join(last_line, 1, NF, OFS)
}
{
key = $1 OFS $2 OFS $3
}
key != prev_key {
if (n > 0) {
print_record()
}
delete col5
delete col6
delete col7
n = 0
}
{
n++
col5[n] = $5
col6[n] = $6
col7[n] = $7
prev_key = key
split($0, last_line)
}
END {print_record()}
그런 다음 우리는 다음을 가집니다:
$ awk -f aggregate.awk input.bed
chr1 69744110 69793325 . -1 -1 0
chr1 82791976 82831348 chr1 82792114/82816285/82828015 82792615/82817077/82829891 501/792/1876
chr1 88599340 88658398 . -1 -1 0
chr1 137772945 137830035 . -1 -1 0
chr1 137875312 137920590 . -1 -1 0
chr1 193433080 193446861 . -1 -1 0
chr10 26483800 26501370 chr10 26484794 26485295 501
chr10 68069913 68089436 . -1 -1 0
chr10 95098349 95113967 . -1 -1 0
chr10 97310211 97335589 . -1 -1 0
chr10 111083097 111118237 chr10 111088928 111090274 1346
chr10 117904141 117947090 chr10 117905334/117918966/117926867 117906320/117919852/117927368 986/886/501
chr11 11521339 11587607 chr11 11523970/11555497/11560639/11564617 11524747/11559868/11562128/11565370 777/4371/1489/753
답변2
질문:
처음 3개 열에 일치하는 항목이 있으면 5,6,7열의 값을 연결합니다.
답변:
perl -lane 'if($.==1){@a=@F;next} if($F[0]eq$a[0]&&$F[1]eq$a[1]&&$F[2]eq$a[2]){$a[4].="/$F[4]";$a[5].="/$F[5]";$a[6].="/$F[6]";}else{for($i=0;$i<@a;$i++){printf "\t%s",$a[$i]};print"";@a=@F}END{for($i=0;$i<@a;$i++){printf "\t%s",$a[$i]};print""}' input.bed
산출:
chr1 69744110 69793325 . -1 -1 0
chr1 82791976 82831348 chr1 82792114/82816285/82828015 82792615/82817077/82829891 501/792/1876
chr1 88599340 88658398 . -1 -1 0
chr1 137772945 137830035 . -1 -1 0
chr1 137875312 137920590 . -1 -1 0
chr1 193433080 193446861 . -1 -1 0
chr10 26483800 26501370 chr10 26484794 26485295 501
chr10 68069913 68089436 . -1 -1 0
chr10 95098349 95113967 . -1 -1 0
chr10 97310211 97335589 . -1 -1 0
chr10 111083097 111118237 chr10 111088928 111090274 1346
chr10 117904141 117947090 chr10 117905334/117918966/117926867 117906320/117919852/117927368 986/886/501
chr11 11521339 11587607 chr11 11523970/11555497/11560639/11564617 11524747/11559868/11562128/11565370 777/4371/1489/753
노트:
더 짧거나 더 우아한 솔루션이 있을 수 있습니다.