私が取得する複数行の出力は次のとおりです。
実際の出力:
GenuineIntel,Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz,CPU0,64,EM64T Family 6 Model 45 Stepping 7,(null),3093,0
GenuineIntel,Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz,CPU1,64,EM64T Family 6 Model 45 Stepping 7,(null),3093,0
#
Bashスクリプトでは、上記の出力を1つの記号で区切られた列と2つのカンマで区切られた列の値を持つ行に変換する必要があります。
予想出力:
GenuineIntel#GenuineIntel,Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz#Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz,CPU0#CPU1 and so on.
どうすればいいですか?
ベストアンサー1
awk
以下は、ファイルの特定の内容に依存しない、より一般的なアプローチです。
awk -F, '{for(i=1;i<=NF;i++){a[NR][i]=$(i)}}
END{
for(i=1;i<NF;i++){printf "%s#%s,",a[1][i],a[2][i]}
print a[1][NF]"#"a[2][NF]
}' file
説明する
for(i=1;i<=NF;i++){a[NR][i]=$(i)}
:各行のフィールド(で区切られた-F,
)を繰り返して、変数をi
1からフィールド数()までのNF
すべての値に設定します。NR
現在の行番号です。あなたの例では1または2です。a[NR][i]=$(i)
行ごとに2D配列を設定し、各フィールドをここに保存します。デフォルトでは、配列は次のa
ようになります。1 2 3 1 1st field of 1st line 2nd field of 1st line 3rd field of 1st line 2 1st field of 2nd line 2nd field of 2nd line 3rd field of 2nd line
など。これにより、これが
a[1][2]
最初の行の2番目のフィールドになります。END{}
:ファイルの残りの部分を処理した後にこれを実行します。for(i=1;i<NF;i++){printf "%s#%s,",a[1][i],a[2][i]}
:すべてのフィールドを繰り返し、最初の行の現在のフィールド#
と2行目の対応するフィールドを印刷します。print a[1][NF]"#"a[2][NF]
:最後のフィールドを印刷します(1行ずつ)。これは別々に行われるため、他のものを印刷してその後にカンマを付けることができますが、これの後には改行文字が続きます。
Perlでも同じアイデアが機能します。
perl -F, -ane 'chomp($F[$#F]);
$k{$.}=\@F;
END{
for($l=0;$l<$#F;$l++){
print "${$k{1}}[$l]#${$k{2}}[$l],"
}
print "${$k{1}}[$#F]#${$k{2}}[$#F]\n"}' file
これは、ファイル内の特定のテキストに依存しないという利点があります。各行に同じ数のカンマ区切りフィールドがある限り、すべてのデータ行に対して機能します。