구분 기호를 사용하여 열을 행으로 분할

구분 기호를 사용하여 열을 행으로 분할

구분 기호를 기준으로 분할하려는 3개의 동적 열이 있는 소스 파일이 있습니다.

아래 이미지는 내 소스 파일과 원하는 출력을 보여줍니다. 둘 다 다음 텍스트로 재현됩니다.

소스 파일 및 예상 출력

원천:

Emp,Hire,ILT,Mgr,Pi
123,Y,UB|VY,,BY|LN|VB
435,N,LN,HA-12/09/2019|LA-13/09/2019,BY|LN|OR
657,Y,,MA-12/09/2019|RA-13/09/2019,VB

원하는 출력:

Emp,hire,ILT,Mgr,Pi
123,Y,UB,,BY
123,Y,VY,,LN
123,Y,,,VB
435,N,LN,HA-12/09/2019,BY
435,N,,LA-13/09/2019,LN
435,N,,,OR
657,Y,,MA-12/09/2019,VB
657,Y,,RA-13/09/2019,VB

답변1

이 AWK 스크립트를 다음과 같이 저장한다고 가정합니다 script.

BEGIN {
                                # Populate an array that lists (is indexed
                                # by) the position of "dynamic" fields.
  split(dynamic,temp,",")
  for (i in temp)
    tosplit[temp[i]] = i
}
{
                                # Determine how many times the current
                                # line will be repeated...
  times = 1
                                # by counting how many times, for each field,
  for (f = 1; f <= NF; f++) {
                                # the "|" separator is replaced by itself.
    repl = gsub(/\|/, "&", $f)
    if ( (repl + 1 ) > times)
      times = (repl + 1 )
  }
                                # For each time the line has to be repeated:
  for (i = 1; i <= times; i++) {
    for (f = 1; f <= NF; f++) {
                                # every "dynamic" field is split on "|", and
                                # only the component which belongs to the
                                # current line repetition is printed;
      if (f in tosplit) {
        split($f, p, "|")
        printf( (f == NF ? "%s"ORS : "%s"OFS), p[i] )
      }
                                # all other fields are printed unchanged.
      else
        printf( (f == NF ? "%s"ORS : "%s"OFS), $f )
    }
  }
}

그런 다음 다음과 같이 호출할 수 있습니다.

awk -v FS=',' -v OFS=',' -v dynamic=3,4,5 -f script source_file

awk분할해야 하는 열의 인덱스("동적" 필드)는 쉼표로 구분된 목록을 보유하는 변수로 전달됩니다.

관련 정보