我有一些这种格式的数据;-
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
将 Python 和列表理解与 itertools 模块结合使用
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