入力として次のデータがあります。
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
- これは最初の列を
([^ ]* )
キャプチャします(スペースが区切り文字であると仮定)。B
第二それからスペース)。 - これは
(.*),
最後のカンマまですべてをキャプチャします。2,3,5
これは
([^,]*$)
行の残りの部分をキャプチャします(たとえば、毎回キャプチャする最後のコンマの後の最後のフィールド)。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
次の行を読み、すべての行が続いて完了するまで同じ手順を実行します。