この形式のデータがあります;-
Type,Fac1,Fac2,Fac3
1,0.1,0.1,0.1
2,0.2,0.2,0.2
3,0.3,0.3,0.3
AWKを使用してデータを次のように変換する必要があります。
Type
1,Fac1,0.1
1,Fac2,0.1
1,Fac3,0.1
2,Fac1,0.2
2,Fac2,0.2
2,Fac3,0.2
3,Fac1,0.3
3,Fac2,0.3
3,Fac3,0.3
つまり、水平方向から垂直方向に変化する「ピボット」動作です。
だから私はこれを試しました:
awk -F ',' '{for (i=2;i<=NF;i++) { if (i==2) {print $1"," $i } else print $1"," $i}}'
答え1
$ cat tst.awk
BEGIN { FS=OFS="," }
NR==1 {
print $1
split($0,tags)
next
}
{
for (i=2; i<=NF; i++) {
print $1, tags[i], $i
}
}
$ awk -f tst.awk file
Type
1,Fac1,0.1
1,Fac2,0.1
1,Fac3,0.1
2,Fac1,0.2
2,Fac2,0.2
2,Fac3,0.2
3,Fac1,0.3
3,Fac2,0.3
3,Fac3,0.3
答え2
perl
カンマで行を区切ります。
perl -sF, -lane '
$.==1 && do{
print shift @F;
@h = @F; next;
};
my $i;
print $F[0], splice(@F,1,1), $h[$i++] while @F > 1;
' -- -,=, file
出力:-
Type
1,0.1,Fac1
1,0.1,Fac2
1,0.1,Fac3
2,0.2,Fac1
2,0.2,Fac2
2,0.2,Fac3
3,0.3,Fac1
3,0.3,Fac2
3,0.3,Fac3
itertoolsモジュールでPythonとリストを理解する
python3 -c 'import itertools as it, sys
ifile = sys.argv[1]
fs,rs = ",","\n"
ofs,ors = fs,rs
with open(ifile) as f:
for nr,l in enumerate(f,1):
L = l.rstrip(rs).split(fs)
if nr == 1:
print(L.pop(0))
H = L
else:
print(*[ofs.join([a,*b])
for a,b in zip(it.repeat(L.pop(0)),zip(L,H))],sep=ors)
' file
拡張正規表現モードのGNU sed:-
sed -Ee '
1{
s/,/\n/;P
s/.*\n//
h;d
}
/\n/!G
s/,/&\n/2
s/^(([^,]*,).*)\n(.*\n)([^,]*),/\1\4\n\2\3/
/\n.*\n/!s/\n/,/
P;D
' file