쉘 스크립트를 사용하여 순환 순서로 행을 열로 바꿉니다.

쉘 스크립트를 사용하여 순환 순서로 행을 열로 바꿉니다.

순환 순서로 행을 열로 바꾸고 두 번째로 나타나는 열 머리글을 무시하고 싶습니다.

예를 들어

나는 다음과 같은 데이터를 가지고 있습니다

[ID] 10
[NAME] TOM
[AGE] 25

[ID] 11
[NAME] SAM
[AGE] 26

출력은 다음과 같아야합니다

[ID]|[NAME]|[AGE]
10|TOM|25
11|SAM|26

다음 awk 명령을 사용해 보았습니다.

awk 'BWGIN { FS="]"; OFS="|";} {for (i=1; i<=NF; i++) a[i,NR]=$i
    max=(max<NF?NF:max)}
    END {for (i=1; i<=max; i++)
          {for (j=1; j<=NR; j++) 
              printf "%s%s", a[i,j], (j==NR?RS:FS)
          }
    }' source.txt

나는 다음과 같은 결과를 얻습니다

[ID][NAME][AGE][ID][NAME][AGE]
10]TOM]25]11]SAM]25

열 이름은 계속 반복되며 Sam의 데이터는 래핑되어야 합니다.

열 이름을 하드코딩하고 해당 값을 추출하지 않고 이를 달성하려면 어떻게 해야 합니까? 100개 이상의 열이 있습니다. 이를 실현하는 데 도움을 주셔서 감사합니다.

답변1

그리고밀러, "xtab"에서 "csvlite" 형식으로 변환:

$ mlr --ixtab --ocsvlite --ofs '|' cat source.txt
[ID]|[NAME]|[AGE]
10|TOM|25
11|SAM|26

답변2

awk 'BEGIN{ OFS="|"; printhdr=1 }
  NF{
    hdr=(hdr=="" ? "" : hdr OFS) $1
    row=(row=="" ? "" : row OFS) $2
    next
  }
  printhdr{ print hdr; printhdr=0 }
  { print row; row="" }
  END{ print row }
' file

헤더 필드와 전치된 행을 변수에 추가하고 hdr필드 row 수가 0이 아닌 경우 필드가 없는 레코드가 발견되면 변수를 인쇄합니다. 플래그가 설정 되면 printhdr헤더는 한 번만 인쇄되고 row변수도 END블록에 인쇄되어 입력 파일의 마지막 조옮김 행을 인쇄합니다.

답변3

awk -v RS= -v OFS='|' '
    NR==1 { for (i=1; i<NF; i+=2) printf "%s%s", $i, (i<(NF-1) ? OFS : ORS) }
    { for (i=2; i<=NF; i+=2) printf "%s%s", $i, (i<NF ? OFS : ORS) }
' file
[ID]|[NAME]|[AGE]
10|TOM|25
11|SAM|26

관련 정보