일부 출력 형식을 지정하기 위해 printf 및 awk를 사용하려고 합니다. 기본적으로 최종 형식은 다음과 같습니다(모든 탭이 구분되어 있음).
chr10 100000624 100000625 10:100000625_A_G
chr10 100000644 100000645 10:100000645_A_C
chr10 100002463 100002464 10:100002464_C_T
chr10 100003241 100003242 10:100003242_G_T
chr10 100003303 100003304 10:100003304_A_G
chr10 10000337 10000338 10:10000338_C_T
chr10 100003515 100003516 10:100003516_A_G
chr10 100003784 100003785 10:100003785_C_T
chr10 100004359 100004360 10:100004360_A_G
chr10 100004440 100004441 10:100004441_C_G
...
시작 파일은 다음과 같습니다(다른 열은 중요하지 않음).
10:100000625_A_G G A
10:100000645_A_C C A
10:100002464_C_T C T
10:100003242_G_T G T
10:100003304_A_G G A
10:10000338_C_T T C
10:100003516_A_G A G
10:100003785_C_T C T
10:100004360_A_G A G
10:100004441_C_G C G ...
...
두 번째 열은 첫 번째 열보다 한 열 작아야 합니다. 원본 파일을 사용하여 기본적으로 다음을 수행했습니다.
awk -F ":" '$1=$1' OFS="\t" <(zcat <filename>) | awk -F "_" '$2=$2' OFS="\t" | awk -v OFMT="%f" 'BEGIN {OFS=FS="\t"} {print "chr"$1, $2-1, $2, $1":"$2"_"$3"_"$4}'
먼저 ID의 시작 부분을 ":"으로 분해한 다음 "_"로 분해했습니다. awk -F "[:_]"...
두 구분 기호를 모두 사용하여 첫 번째 열을 나눌 수도 있지만 결국에는 차이가 없을 것이라고 생각합니다.
숫자가 과학적 표기법(12000000과 같은 숫자)으로 보고되는 몇 가지 경우를 제외하고는 작동하지만 이는 내가 원하지 않습니다. printf를 사용하면 과학적 표기법을 취소할 수 있어야 하는데 작동할 수 없습니다.
내 첫 번째 생각은 첫 번째와 네 번째 열을 문자열로, 두 번째와 세 번째 열을 소수점 없는 부동 소수점 숫자로 원한다는 것이었습니다. 그래서 다음을 시도했습니다 awk '{printf "%s\t%4.0f\t%4.0f\t%s\n" "chr"$1, $2-1, $2, $1":"$2"_"$3"_"$4}'
. 그러나 다음과 같은 오류 메시지가 나타납니다.
awk: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
`%s %4.0f %4.0f %s
chr10'
^ ran out for this one
형식 문자열이 내 파일의 필드 수에 비해 너무 긴 것 같지만 이유는 확실하지 않습니다. printf를 사용하다가 한 가지 기능을 발견했습니다. 이렇게 하면 awk '{printf "\t%s\t%4.0f\t%4.0f\t\n" "chr"$1, $2-1, $2, $1":"$2"_"$3"_"$4}'
다음과 같은 결과를 얻습니다.
100000624 100000625 10
chr10 100000644 100000645 10
chr10 100002463 100002464 10
chr10 100003241 100003242 10
chr10 100003303 100003304 10
chr10 10000337 10000338 10
chr10 100003515 100003516 10
chr10 100003784 100003785 10
chr10 100004359 100004360 10
chr10 100004440 100004441 10
chr10
따라서 첫 번째 열은 다른 모든 열에 비해 한 행 아래로 밀려나고 네 번째 열은 잘립니다. 답장에서 printf 구문이 어떻게 작동하는지 설명해 주시면 정말 감사하겠습니다. 매우 감사합니다!
답변1
형식 문자열 뒤에 쉼표가 누락되었습니다.
awk -F'[:_\t]' '{ printf "%s\t%4.0f\t%4.0f\t%s\n", "chr"$1, $2-1, $2, $1":"$2"_"$3"_"$4 }' file
# ^
# |
# this one
답변2
문제를 전혀 재현할 수는 없지만 문제가 있다고 가정하면 도움이 될 수 있습니다.
$ cat tst.awk
BEGIN { OFS="\t"; OFMT="%d" }
{
split($1,f,/[:_]/)
print "chr"f[1], f[2]-1, f[2], $1
}
$ awk -f tst.awk file
chr10 100000624 100000625 10:100000625_A_G
chr10 100000644 100000645 10:100000645_A_C
chr10 100002463 100002464 10:100002464_C_T
chr10 100003241 100003242 10:100003242_G_T
chr10 100003303 100003304 10:100003304_A_G
chr10 10000337 10000338 10:10000338_C_T
chr10 100003515 100003516 10:100003516_A_G
chr10 100003784 100003785 10:100003785_C_T
chr10 100004359 100004360 10:100004360_A_G
chr10 100004440 100004441 10:100004441_C_G
%d
형식이 원하는 대로 작동하지 않지만 %4.0f
작동 OFMT="%d"
한다면 OFMT="%4.0f"
.
첫 번째 열이 아래로 밀리고 네 번째 열이 잘린다고 언급한 내용은 아마도 입력에 DOS 줄 끝이 있다는 의미일 것입니다.https://stackoverflow.com/questions/45772525/why-does-my-tool-output-overwrite-itself-and-how-do-i-fix-it.
답변3
사용앗유틸리티를 사용하면 다음과 같이 할 수 있습니다.
printf -v fmt '%s\t' '%s' '%4.0f' '%4.0f' '%s\n'
awk -F '\t' -v fmt="${fmt%?}" '
{
split($1, a, /[:_]/)
f1 = "chr" a[1]
f2 = (f3 = a[2])-1
f4 = sprintf("%4.0f", f3)
sub(/:[^_]+/, ":"f4, $1)
printf fmt, f1, f2, f3, $1
}
' file