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

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

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

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

oneliner는 여러 조각으로 나뉩니다.

입력 파일의 필드 구분자로 탭 문자를 설정합니다.

BEGIN { FS="\t" }

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

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

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

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

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

관련 정보