행 머리글을 유지하면서 데이터 행을 단일 열로 이동

행 머리글을 유지하면서 데이터 행을 단일 열로 이동

다음과 같은 탭으로 구분된 형식으로 생성된 보고서가 있습니다.

UNIT  TC    CC    PC    TCP   FTX   FRX   
HOUSE 55    65    75    85    95    105
CAR   100   200   300   400   500   600
H2    5     10    15    20    25    30
C2    10    20    30    40    50    60

다음 형식으로 변경해야 합니다.

HOUSE TC    55
HOUSE CC    65
HOUSE PC    75
HOUSE TCP   85
HOUSE FTX   95
HOUSE FRX   105
CAR   TC    100
CAR   CC    200
CAR   PC    300
CAR   TCP   400
CAR   FTX   500
CAR   FRX   600

등.

SED AWK BASH와 같은 표준 도구를 사용하고 싶지만 어떤 제안이라도 환영합니다. 이 코드는 사전에 데이터를 구문 분석하고 연결하는 데 사용한 BASH 스크립트에 삽입됩니다. 따라서 항목 수는 항상 동일하며 보고 내용은 변경되지 않습니다.

답변1

노력하다:

$ awk 'BEGIN { FS="\t" } NR==1 { split($0,header,"\t") ; next } { for(i=2;i<=NF;i++) print $1,header[i],$i }' data
HOUSE TC 55
HOUSE CC 65
HOUSE PC 75
HOUSE TCP 85
HOUSE FTX 95
HOUSE FRX 105
CAR TC 100
CAR CC 200
CAR PC 300
CAR TCP 400
CAR FTX 500
CAR FRX 600
H2 TC 5
H2 CC 10
H2 PC 15
H2 TCP 20
H2 FTX 25
H2 FRX 30
C2 TC 10
C2 CC 20
C2 PC 30
C2 TCP 40
C2 FTX 50
C2 FRX 60

안감은 조각으로 나뉩니다.

입력 파일의 필드 구분 기호로 탭을 설정합니다.

BEGIN { FS="\t" }

첫 번째 줄( NR==1)이 필드로 분할되어 배열에 저장되는 경우 header. 이는 모든 필드 $1, $2, ...를 복사하여 for 루프에 저장하는 것보다 간단합니다. 또한 이 next명령은 라인 1이 다음 코드에 의해 처리되는 것을 방지합니다. 이는 다른 라인에만 적용됩니다. ( 더 심각한 결과를 초래 FS하는 대신 "\t"...)

NR==1 { split($0,header,"\t") ; next }

각 줄( NR!=1) 에 대해 $2...$NF$1 접두사가 붙은 모든 필드( )와 필드 이름( )을 인쇄합니다 header[i].

{ for(i=2;i<=NF;i++) print $1,header[i],$i }

OFS=FS="\t"블록 설정은 필드 사이에 탭을 사용 BEGIN합니다 print. 모든 출력 라인을 다시 포맷해야 하기 때문에 답변에서 이것을 변경하지 않았습니다.

관련 정보