以前のタグでは、awkプレーンコードを使用してcsv列を保持します。答えが提供されました。ここ寄稿者:@steeldriver。
次に、csvファイルの一部の列を転置して新しい列を取得したいと思います。
データの説明は次のとおりです。
入力の最初の行には国(複数のフィールドが空白)が含まれ、2行目には処理するタイトルが含まれています。
転置された列は、国に基づいて最後の空の列で始まります。国ごとに列数が異なるわけではありません。 2つまたは20の国の列があるかもしれません。
例:
- 入力する:
file.csv
,,,fr,ch num,nom,date reg,match flag_fr,match flag_ch 0001,AA,2020-05-15,reg1_fr,reg2_ch 0002,AAA,2020-05-20,,reg3_ch
- 出力:
file1.csv
num,nom,date reg,match flag,country 0001,AA ,2020-05-15,reg1_fr,fr 0002,AAA,2020-05-20, _fr,fr 0001,AA ,2020-05-15,reg2_ch,ch 0002,AAA,2020-05-20,reg3_ch,ch
私は以下を使用しましたパスワード、結果は正確ですが、他のすべてのフィールドを手動で宣言する必要があります。例:
awk -F, '
BEGIN{OFS=FS}
NR==2{n = split($0,a); print "num,nom,date reg,match country,flag"; next}
{for(i=4;i<=NF;i++) if (a[i] !=""){ print $1,$2,$3,a[i],$i} }
' < file.csv>file1.csv
結果file1.csv
num,nom,date reg,match country,flag
0001,AA,2020-05-15,match flag_fr,reg1_fr
0001,AA,2020-05-15,match flag_ch,reg2_ch
0002,AAA,2020-05-20,match flag_fr,
0002,AAA,2020-05-20,match flag_ch,reg3_ch
可能であれば、通常のawk
コードを使用してどうすればよいですか?
答え1
$ cat tst.awk
BEGIN { FS=OFS="," }
NR==1 {
for (numHdrs=1; numHdrs<=NF; numHdrs++) {
if ( $numHdrs != "" ) {
break
}
}
numHdrs--
next
}
{
hdr = ""
for (i=1; i<=numHdrs; i++) {
hdr = hdr $i OFS
}
}
NR == 2 {
for (i=numHdrs+1; i<=NF; i++) {
country[i] = $i
}
print hdr "match flag", "country"
next
}
{
for (i=numHdrs+1; i<=NF; i++) {
print hdr country[i], $i
}
}
。
$ awk -f tst.awk file.csv
num,nom,date reg,match flag,country
0001,AA,2020-05-15,match flag_fr,reg1_fr
0001,AA,2020-05-15,match flag_ch,reg2_ch
0002,AAA,2020-05-20,match flag_fr,
0002,AAA,2020-05-20,match flag_ch,reg3_ch