ファイルを解析するためのawkコマンド

ファイルを解析するためのawkコマンド

次のテキストファイルがあります。最初の3行をお見せします。

chrom   st  end gene    strand  c1  c2  c3  c4  c5  c6  c7  c8  c9  c10 c11 c12 c13 c14
chr6    3345    3543    geneA   +   36  -23 -1  3   1250    946 416 458 475 417 58  80  2   14
chr9    1302    1389    geneB   -   8   -10 -18 -8  2896    2128    635 955 372 385 -20 31  -7  -7

最初の行はヘッダー行なので、そのまま印刷したいと思います。

次に、後続の行(つまり、行2から始まる)の最初の5つのフィールドをそのまま(チェーン情報まで)印刷し、その後、そのフィールドの値(フィールド6から始まる)が> = 100の場合、値を印刷します。 。現状のままフィールド値が<100の場合はNAに置き換えます。

したがって、私の出力ファイルは次のようになります(理想的にはタブで区切られています)。

chrom   st  end gene    strand  c1  c2  c3  c4  c5  c6  c7  c8  c9  c10 c11 c12 c13 c14
chr6    3345    3543    geneA   +   NA  NA  NA  NA  1250    946 416 458 475 417 NA  NA  NA  NA
chr9    1302    1389    geneB   -   NA  NA  NA  NA  2896    2128    635 955 372 385 NA  NA  NA  NA

答え1

awk 'NR > 1 { for (i = 6; i <= NF; i++) if ($i < 100) $i = "NA" }; 1' yourfile.txt

拡張コメント:

NR > 1 {                         # skipping NR == 1, the first line
    for (i = 6; i <= NF; i++)    # column 6 to the end, skipping first 5
        if ($i < 100) $i = "NA"  # self-explanatory
}

1 # print all lines; 1 evaluates to true, and default action is print

編集:これを設定する方法はいくつかありますOFS。私が考えることができる最もきれいな方法は、OFS='\t'ファイル名を前に付けることです。

awk '...' OFS='\t' file.txt
awk -v OFS='\t' '...' file.txt
awk 'BEGIN { OFS="\t" }; ...' file.txt

答え2

jw013はすでに良いawkソリューションを提供していますが、Perlに言及して以来:

perl -lane 'map{$_="NA" if $_<100}@F[5..$#F] if $.>1; print join "\t", "@F"' file 

説明する

  • perl -lane:各入力行を処理し(-n)、スペースで配列@F-a)に分割し、指定されたスクリプトを実行します-e。各行から末尾の改行を削除し、-l各ステートメントに追加します。\nprint

  • map{$_="NA" if $_<100}@F[5..$#F]@F 配列の6番目から最後までの各要素(フィールド)が100未満の場合、その要素を「NA」に変更します。

  • if $.>1;: 前の内容は、map{}最初の行でない場合にのみ実行されます。

  • print join "\t", "@F"'@Fタブを使用して配列の各要素を連結し(jw013の回答の説明で要求)、印刷します。

答え3

sed '1n;s|$| |;:na
    s|\([+-] .*\) [+-]*[0-9]\{1,2\} |\1 NA |
    t na;s| $||'

あなたが示したデータをsed s///;t見ると、この小さな機能が機能しない理由はありません。(私が逃したかもしれない最後のコラムを指摘してくれたjw013に感謝します。)これは、置き換える内容がなくなるまで、1行+/-からaの後の1〜2桁の数字のすべての文字列をその前のすべての文字列に置き換えます。NA

sed以下は、再帰のない既存のスペースを活用する別のバージョンですh

sed '1n;h;s|.*[+-] ||;s|$| |
    s| [+-]*[0-9]\{1,2\} | NA |g
    x;G;s|\([+-] *\).*\n|\1|;s| $||'

これは同じマーカーと分割線に依存します。前半部分はh前の空間では変更されずにそのまま残り、パターン空間では完全に除去される。次に、1,2 個の数字の単語をすべてグローバルに置き換え、前のスペースに追加し、hパターンと前のスペースを変更し、x追加操作の結果として挿入されたhタグと ewline の間のすべての項目を削除します。\n

関連情報