カンマ区切りフィールドを別々の行に分割する方法

カンマ区切りフィールドを別々の行に分割する方法

入力ファイル:

A    B       C    D
1   2,3,4,5 6,7 8,9,10,11

結果ファイル:

A       B     C     D
1       2     6     8
        3     7     9
        4           10
        5           11

答え1

perl -MList::Util=max -lane '
  @F = map {[split /,/]} @F;
  $n = max map {scalar @$_} @F;
  foreach $i (0..$n-1) {print join "\t", map {$_->[$i]} @F};
' file

答え2

GNUを使用してdatamashデータを2回置き換えます。最初の転置は、スペースを入力区切り文字として使用し、カンマを出力区切り文字として使用します。あなたの質問の例に基づいて、次のデータを提供します。

A,1
B,2,3,4,5
C,6,7
D,8,9,10,11

その後、厳密モードをオフにして(レコード内のフィールド数が同じである必要はありません)、空白を不足しているフィールドとして追加しながら、入力と出力の区切り文字としてコンマを使用して再配置します。これにより

A,B,C,D
1,2,6,8
 ,3,7,9
 ,4, ,10
 ,5, ,11

次に、結果を実行して、column質問に似た素敵なテーブルに書式設定します。

A  B  C  D
1  2  6  8
   3  7  9
   4     10
   5     11

完全なコマンドパイプライン:

datamash -W --output-delimiter=, transpose <file |
datamash -t , --filler=' ' --no-strict transpose |
column -s , -t

答え3

awk+によってpaste

awk '{
       for(i=1; i<=NF; i++) {
           gsub(",", "\n", $i); close("col_"i); print $i >>"col_"i
       }
}' infile  && paste col_*

ノート:

  • 後でawkによって生成された一時ファイルを削除できますrm -f col_*\
  • 列を適切にソートするpasteためにコマンド出力をに渡すこともできます。|column -s $'\t' -tn2つの列に2つのファイルを印刷します。もっと学ぶ。

答え4

使用幸せ(以前のPerl_6)

raku -e 'lines[0].put; my @a; @a.push( $_.split(",")) for lines.split("\t"); \
      my $i = @a>>.elems.max; my @b; for @a -> $a { for ^$i { \
      @b[$++].push($a[$_] // "␀".Str)}};   \
      $_.put for @b>>.join("\t");'   file

または

raku -e 'lines[0].put; my @a; @a.push: $_.split(",") for lines.split("\t"); \
      my $i = @a>>.elems.max; my @b; for @a -> $a { \
      @b[$++].push($a[$_] // "␀".Str) for ^$i }; \
      put($_, "\t") for [Z] @b.rotor($i);'  file

入力例:

A   B   C   D
1   2,3,4,5 6,7 8,9,10,11,12

出力例(列の区切り\t):

A   B   C   D
1   2   6   8
␀   3   7   9
␀   4   ␀   10
␀   5   ␀   11
␀   ␀   ␀   12

上記は、Perlプログラミング言語ファミリーであるRakuで書かれたソリューションです。入力テキストファイルが次のようになるとします。2行(数百にも及ぶ可能性がある)列の間にタブで区切られた各行と、\t,列の要素を区切るコンマ付きのファイル。

簡単に言えば、最初の行はputヘッダー行です。配列は@a後続の行で埋められ、最初に\tタブ(列表示)に分割され、次にコンマ,に分割されます。@a次に、配列の最長要素を計算するために使用します@a>>.elems.max;。次に、要素は@a新しく宣言された配列にコピーされますが、Rakuの「define-OR」演算子は未定義の位置に挿入するために使用されること@bに注意することが重要です。 (このコードは空の文字列でも機能します。)最後に、配列データが(印刷)出力されます。//"".Str@bput

[出力の列が正しくソートされました。無効な並べ替えは、プレースホルダ文字の幅が原因で発生します

たとえば、スペースで区切られている場合は、ヘッダー行を最初に(個別に)処理できます。

my $header=lines[0].split("\s"); $header.join("\t").put;

または(より簡単に)

lines[0].split("\s").join("\t").put;

https://raku.org

関連情報