シェルスクリプトを使用して、循環順に行を列に置き換えます。

シェルスクリプトを使用して、循環順に行を列に置き換えます。

循環順に行を列に置き換え、2番目に表示される列見出しを無視したいと思います。

例えば

私は次のデータを持っています

[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 以外の場合、フィールドのないレコードが見つかった場合は変数を印刷します。フラグが設定されると、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

関連情報