printfとAWKを使用して出力形式を正しく指定する

printfとAWKを使用して出力形式を正しく指定する

いくつかの出力フォーマットを指定するために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 ...
...

2番目の列は1番目の列より1列小さい必要があります。元のファイルを使用して、デフォルトで次のことを行いました。

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を使用すると、科学的な表記を取り消すことができるはずですが、機能することはできません。

私の最初の考えは、最初と4番目の列を文字列として、2番目と3番目の列を小数点のない浮動小数点数として欲しいということでした。だから私は次を試しました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を使って1つの機能を見つけました。これにより、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 

したがって、最初の列は他のすべての列と比較して1行下に押され、4番目の列は切り捨てられます。返信で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

おすすめ記事