AWK를 사용하여 간단히 데이터 변환

AWK를 사용하여 간단히 데이터 변환

이 형식의 데이터가 있습니다 ;-

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

관련 정보