
次の構造の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 分割() 関数これは分かれています文字列/ライン/レコード($0
awkで行全体を指すひもここで)はハッシュで区切られたフラグメントに分割され、最初のレコードにのみas条件を持つ配列#
に格納されます。clstr
NR==1
NR==2{split($0, type, /#/)}
:上記と同じことを行い、という配列に保存され、type
as条件を持つ2番目のレコードでのみ実行されますNR==2
。NR>2{ ... }
:このコードブロックは、そのコードブロックを含むレコード/行に対して実行されます。窒素数量右レコード数>2split($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]
配列にその値を印刷します。clstr
type
入力を処理する前にすべての項目を交換してください。タブハッシュ文字を使用して
#
(他の文字を使用できますが、ファイルにその文字が表示されないことを確認する必要があります)、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
答え2
Awk
固定ソリューション「フィールドは降順で表示されます」ゲーム1からゲーム3まで:
awk 'NR == 1 {
group1 = $1; group2 = $2; group3 = $3
}
NR == 2 {
group1 = group1 OFS $1;
group2 = group2 OFS $2;
group3 = group3 OFS $3
}
NR > 2 {
if (NF == 3) { cl1[NR - 2] = $1 }
if (NF >= 2) { cl2[NR - 2] = $(NF - 1) }
cl3[NR - 2] = $(NF)
}
END {
traverse(cl1, group1);
traverse(cl2, group2);
traverse(cl3, group3)
}
function traverse(cl, gr) {
len = length(cl);
for (i = 1; i <= len; i++) {
print cl[i], gr
}
}' OFS='\t' file
出力:
g1 cluster01 typeA
g2 cluster01 typeA
g3 cluster01 typeA
g4 cluster02 typeA
g5 cluster02 typeA
g6 cluster02 typeA
g7 cluster02 typeA
g8 cluster03 typeB
g9 cluster03 typeB
g10 cluster03 typeB
g11 cluster03 typeB
g12 cluster03 typeB