行1と2を追加の列にコピー

行1と2を追加の列にコピー

次の構造のfile.txt(タブ区切り)があります。

cluster01   cluster02   cluster03 ... cluster72   
typeA_1 typeA_1 type2 ...
g1_A    g4_D    g8_H
g2_B    g5_E    g9_I
g3_C    g6_F    g10_J
    g7_G    g11_K
        g12_L

ファイルには72個の列があり、各列には可変長があります。

file.txtを次のようにnewfile.txtに再フォーマットしたいと思います。

g1_A    cluster01   typeA_1
g2_B    cluster01   typeA_1
g3_C    cluster01   typeA_1
g4_D    cluster02   typeA_1
g5_E    cluster02   typeA_1
g6_F    cluster02   typeA_1
g7_G    cluster02   typeA_1
g8_H    cluster03   type2
g9_I    cluster03   type2
g10_J   cluster03   type2
g11_K   cluster03   type2
g12_L   cluster03   type2

ベストアンサー1

別のシンプルawk+sedどのくらいの列があるのに加えて、3行以上のインデントがある方法です。

awk 'NR==1{split($0, clstr, /#/)} NR==2{split($0, type, /#/)}
     NR>2 {split($0, g, /#/); for (x in g) if(g[x]!="") print g[x], clstr[x], type[x]
}' <(sed -E 's/\t/#/g' infile)

説明する:

  • NR==1{split($0, clstr, /#/)}a:私たちは使用したawk 分割() 関数これは分かれています文字列/ライン/レコード$0awkで行全体を指すひもここで)はハッシュで区切られたフラグメントに分割され、最初のレコードにのみas条件を持つ配列#に格納されます。clstrNR==1

  • NR==2{split($0, type, /#/)}:上記と同じことを行い、という配列に保存され、typeas条件を持つ2番目のレコードでのみ実行されますNR==2

  • NR>2{ ... }:このコードブロックは、そのコードブロックを含むレコード/行に対して実行されます。窒素数量レコード数>2

    • split($0, g, /#/):最初と2番目の項目と同じで、という配列に保存されますg
    • for (x in g) if(g[x]!="") print g[x], clstr[x], type[x]:配列インデックスの要素を繰り返しg、その値がnullでない場合は、まず配列からその値をif(g[x]!="")印刷してから、g[x]配列にその値を印刷します。clstrtype

    入力を処理する前にすべての項目を交換してください。タブハッシュ文字を使用して#(他の文字を使用できますが、ファイルにその文字が表示されないことを確認する必要があります)、awkに渡します。

    <(sed 's/\t/#/g' infile)  ## or <(tr '\t' '#'< infile)
    

入力する(商標分離):

cluster01   cluster02   cluster03   ... cluster72
typeA_1 typeA_1 type2   ...
g1_A    g4_D    g8_H
g2_B    g5_E    g9_I
g3_C    g6_F    g10_J
    g7_G    g11_K
        g12_L

出力:

g1_A cluster01 typeA_1
g4_D cluster02 typeA_1
g8_H cluster03 type2
g2_B cluster01 typeA_1
g5_E cluster02 typeA_1
g9_I cluster03 type2
g3_C cluster01 typeA_1
g6_F cluster02 typeA_1
g10_J cluster03 type2
g7_G cluster02 typeA_1
g11_K cluster03 type2
g12_L cluster03 type2

おすすめ記事