Linuxでピボットテーブルを実行して、1つのレコードを複数のレコードに変換できますか?

Linuxでピボットテーブルを実行して、1つのレコードを複数のレコードに変換できますか?

私たちは以下のデータを持っています

 ABC|RAM|BANGALORE|100,200,300

上記のデータを複数のレコードに分割するためにピボット/ループを実行できますか?

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

最後の列にカンマ区切り文字を含む複数の値に基づいてレコード数を生成する必要があります。

Linuxシェルでできることはありますか?

答え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

関連情報