Linux에서 피벗 테이블을 실행하여 1개의 레코드를 여러 레코드로 변환할 수 있나요?

Linux에서 피벗 테이블을 실행하여 1개의 레코드를 여러 레코드로 변환할 수 있나요?

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

 ABC|RAM|BANGALORE|100,200,300

위의 데이터를 여러 레코드로 분할하기 위해 피벗/루프를 실행할 수 있습니까?

ABC|RAM|BANGALORE|100
ABC|RAM|BANGALORE|200
ABC|RAM|BANGALORE|300

마지막 열에 쉼표 구분 기호가 있는 여러 값을 기반으로 레코드 수를 생성해야 합니다.

리눅스 쉘에서 할 수 있는 일이 있나요?

답변1

나는 이것을 위해 쉘 자체를 사용하지 않을 것입니다.

또 다른 awk 구현

$ awk 'BEGIN{OFS=FS="|"} {split($NF,a,","); for(i in a) {$NF = a[i]; print}}' data
 ABC|RAM|BANGALORE|100
 ABC|RAM|BANGALORE|200
 ABC|RAM|BANGALORE|300

또는밀러

$ mlr --nidx --fs '|' nest --explode --values --across-records --nested-fs ',' -f 4 data
 ABC|RAM|BANGALORE|100
 ABC|RAM|BANGALORE|200
 ABC|RAM|BANGALORE|300

또는 더 컴팩트

mlr --nidx --fs '|' nest --evar ',' -f 4 data

만약 너라면진짜쉘을 사용한 다음 최근 bash를 사용해야 합니다.

#!/bin/bash

while IFS='|' read -a fields; do 
  IFS=',' read -a vals <<<"${fields[ -1]}"
  unset 'fields[ -1]'
  for v in "${vals[@]}"; do
    printf '%s|' "${fields[@]}" 
    printf '%s\n' "$v"
  done 
done < data

답변2

awk를 사용하세요:

awk -F "," '                      #Sets field separator to ,
    NF<2{print;next}
    {
        print $1                  #Print first line up to ,
        sub(/[^|]*$/,"",$1)       #Remove all that is after | in $1
        for(i=2;i<=NF;i++){       #Print each remaining field after the first field
            printf "%s%s\n",$1,$i
        }
    }
' file

샘플 파일:

ABC|RAM|BANGALORE|100,200,300
ABC|BA00|
ABC|RAM|BANGALO00|200,300

산출:

ABC|RAM|BANGALORE|100
ABC|RAM|BANGALORE|200
ABC|RAM|BANGALORE|300
ABC|BA00|
ABC|RAM|BANGALO00|200
ABC|RAM|BANGALO00|300

답변3

예를 들어:

#!/usr/bin/env sh

s="ABC|RAM|BANGALORE|100,200,300"

header="$(echo "$s" | rev | cut -d'|' -f2- | rev)"

list="$(echo "$s" | rev | cut -d'|' -f1 | rev)"

IFS=','
for i in $list
do
    printf "%s|" "$header"
    printf "%s\n" "$i"
done

산출:

ABC|RAM|BANGALORE|100
ABC|RAM|BANGALORE|200
ABC|RAM|BANGALORE|300

관련 정보