使用帶有 AWK 的 printf 來正確格式化我的輸出
我正在嘗試使用 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 語法是如何工作的,我將非常感激。太感謝了!
您只是在格式字元串後缺少一個逗號,例如
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
我根本無法重現您的問題,但假設它確實存在,這可能會對您有所幫助:
$ 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
format 不能滿足您的需要,但%4.0f
可以,那麼只需更改OFMT="%d"
為OFMT="%4.0f"
.您提到的關於第一列被下推和第四列被截斷的內容可能意味著您的輸入中有 DOS 行結尾,請參閱https://stackoverflow.com/questions/45772525/why-does-my-tool-output -覆蓋本身和如何做我修復它。