AWKを使用して2つの列の形式を変更する

AWKを使用して2つの列の形式を変更する

入力として次のデータがあります。

A 1,2
B 3,2,5
C 6,7
D 1,3,5,8

AWKを使用して次の出力をどのように取得できますか?

A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8

答え1

$ awk -F '[ ,]' '{ for (i = 2; i <= NF; ++i) print $1, $i }' file
A 1
A 2
B 3
B 2
B 5
C 6
C 7
D 1
D 3
D 5
D 8

これは、行をスペースまたはカンマ区切りのフィールドで構成されるものとして扱います。各行について、awkプログラムは行の最後まで第2のフィールドを繰り返す。各フィールドについて出力されます。最初現在のフィールドを持つ行のフィールド。

答え2

awk '{gsub(/,/,  "\n" $1 " "); print}' file

このソリューションでは、,各 ""を次に置き換えます。"\n$1 "

答え3

sed拡張正規表現エンジンを有効にすると、次のことができます。

$ sed -re '
   s/^((\S+\s+)[^,]+),/\1\n\2/
   P;D
' file

私たちはPerlできます:

$ perl -F'\s+|,' -lane '
   print join $", splice @F, 0, 2, $F[0] while @F > 1;
' file

現在のレコードをスペースまたはカンマに分割し、ゼロインデックス配列に保存します@F

配列の最初の2つの要素を連結し、単一のスペースに結合して$"印刷します。また、削除された両方の要素を最初の要素に置き換えます。 1つの要素だけが残るまでこのプロセスを繰り返します。

答え4

sedこれがオプションの場合は、次のようにできます。

sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/; ta' infile

次の入力を考慮してください。

B 2,3,5,6
C 6,7
D 1,3,5,8
  1. これは最初の列を([^ ]* )キャプチャします(スペースが区切り文字であると仮定)。B第二それからスペース)。
  2. これは(.*),最後のカンマまですべてをキャプチャします。2,3,5
  3. これは([^,]*$)行の残りの部分をキャプチャします(たとえば、毎回キャプチャする最後のコンマの後の最後のフィールド)。6

    • したがって、\1\2\n\1\3最初の行の最初のループが実行されたときの結果は次のようになります。

      sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/;q ;ta' infile 
      B 2,3,5
      B 6
      
    • 次のループ実行の結果は次のとおりです。

      B 2,3
      B 5
      B 6
      
    • 次回走ると…
    • 最後に、最後のループ実行の最初の行は次のように出力されます。

      sed -E ':a s/^([^ ]* )(.*),([^,]*$)/\1\2\n\1\3/ ;ta ;q' infile
      B 2
      B 3
      B 5
      B 6
      
    • 次の行を読み、すべての行が続いて完了するまで同じ手順を実行します。

関連情報