私の入力ファイルが次のようになっているとしましょう。
ID1
1 5
6 8
ID2
1 4
5 7
私はこれらのタスクを組み合わせることができるループを定式化したいと思います。
行が文字で始まる場合:フィールドの後に '\ n'を残します。
行が数字で始まる場合:
sed 's / \ t /, / g; s / \ n /, / g '
次の行がsed 's / \ t /, / g'
文字()で始まらない限り、各 '\ t'と '\ n'をコンマ()で置き換えます。
予想出力:
ID1
1, 5, 6, 8
ID2
1, 4, 5, 7
答え1
sed '/^[0-9]/{:a;s/[\t\n ]\+/,/g;N;/\n[A-Z]/!ba;}'
行われること。
説明する:
/^[0-9]/
数字で始まる行だけを一致させ、その行にコマンドグループを適用します。
{}
要求されたコマンドグループ
{:a;s/[\t\n ]\+/,/g;N;/\n[A-Z]/!ba;}
各行を繰り返し、文字で始まる行が出るまで、すべてのスペース、タブ、および改行をコンマで置き換えます。
答え2
次のようにこれを達成できるはずです。現在の行が数字で始まる場合は、次の行をパターンスペースに追加してから、スペース、タブ、および改行シーケンスをカンマスペースで置き換えます。
$ sed '/^[0-9]/{N;s/[ \t\n]\+/, /g}' file
ID1
1, 5, 6, 8
ID2
1, 4, 5, 7
答え3
awk
私はより多くの制御を提供し、問題を要約することを選択します。
awk 'BEGIN{FS="\t"; OFS=","}
/^[^A-Z]/ {for (i=1; i<=NF; i++) {if (!a) a=$i; else a=a OFS $i} next}
{if (a) print a; a=""; print}
END{print a}'
説明する
BEGIN{FS="\t"; OFS=","}
入力フィールド区切り記号をタブに設定し、出力フィールド区切り文字をコンマに設定します。/^[^A-Z]/ {for (i=1; i<=NF; i++) {if (!a) a=$i; else a=a OFS $i} next}
大文字で始まらない行では、値を変数に保存しますa
。{if (a) print a; a=""; print}
残りの場合(たとえば、大文字で始まる行)、保存された値は現在の行と一緒に印刷されます。END{print a}
ファイル全体を処理した後、最後のブロックの値を使用して最後に保存された変数を印刷します。
出力を表示します。
$ awk 'BEGIN{FS="\t"; OFS=","}/^[^A-Z]/ {for (i=1; i<=NF; i++) {if (!a) a=$i; else a=a OFS $i} next} {if (a) print a; a=""; print} END{print a}' file
ID1
1,5,6,8
ID2
1,4,5,7
sedでは、いつでも-e
オプションを使用してコマンドを組み合わせることができることに注意してください。
答え4
tr -s '\t\nI' ' \n' <<\DATA |\
sed 's/^/I/;s/ */\n/;s/ *[0-9]/,&/g'
ID1
1 5
6 8
ID2
1 4
5 7
DATA
出力
ID1
1, 5, 6, 8
ID2
1, 4, 5, 7
まず
tr
、すべてのタブと改行を空白に変換します。そしてすべての大文字がラップされます。また、担当者を圧迫します。この時点では、sed
次の入力が渡されるため、操作が非常に簡単になります。^D [num] [num] [num] [num] [num] ... [num] $
次の
sed
場所私返し、行の最初のスペースを改行に置き換え、後のスペースをすべて消去します。行の残りの各スペースの前にコンマを追加すると完了です。