パターンの最初の部分を失うことなくパターンが見つかるまで、複数の行を1つにリンクします。

パターンの最初の部分を失うことなくパターンが見つかるまで、複数の行を1つにリンクします。

次のスキーマがあります。

i-095erwr244r22cfeaa
TF-CLIENT
TF-StKML2
i-0c23232ac153534c5d
TF-CLIENT
TF-COMMON
TF-STEERR
i-043434e0934347eb5
TF-CLIENT
TF-ADFS
TF-COMMON
TF-STCLUSTER_1
TF-SwewCLUSTER3

私は次のような出力が欲しい

i-095erwr244r22cfeaa,TF-COMMON;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3

私はこれを試みます:

awk 'BEGIN{RS="i-"}NF>1{print substr(gensub(/\n/,";","g"),0,length($0)-0)}' sg1.txt

同様の投稿に基づいていますここにあります。私は次のような結果を得る

095erwr244r22cfeaa;TF-COMMON;TF-StKML2;
0c23232ac153534c5d;TF-CLIENT;TF-COMMON;TF-STEERR;
043434e0934347eb5;TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3

したがって、「i-0」パターンの先頭を切り取り、すべての出力にセミコロンを追加します。最初のエントリにはコンマが必要です。使ってみようかと思いました。sed結果から最初のセミコロンを変更します。しかし、最初に全体の出力をどのように取得できますか?

答え1

私のGNUsed提案tr

tr '\n' ';' < file | sed -E 's/(i-0[^;]*);/\n\1,/g'

出力:

i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3;

答え2

$ awk '/^i-/{if (NR>1) print rec; rec=$0 ","; next} {rec=rec $0 ";"} END{print rec}' file
i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3;

または、各行の末尾にセミコロンが必要かどうかに応じて、次のようにします。

$ awk '/^i-/{if (NR>1) print rec; rec=$0; sep=","; next} {rec=rec sep $0; sep=";"} END{print rec}' file
i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3

答え3

あなたは:

BEGIN { RS="i-" }
NF>1 {
    print substr( gensub(/\n/,";","g"), 0, length($0)-0)
}

ここでは、複数行を 'i-' で区切って直ちに失われるように 1 つのレコードに変換し、NL("\n") を ';' に変換します。 substrはあなたにとってあまり役に立たないようです。

独自に再適用すると、次のようにお客様のニーズに合わせることができます。

BEGIN { RS="i-" }
NF>1 {
    print gensub("^(.*);$", "i-\\1", "g", gensub(/\n/,";","g"))
}

これは、以前に行った操作を内部的に実行し、複数のフィールドを連結し、NLを「;」に変換するgensubに依存します。外部では、単にこれを入力として受け入れ、「i-」を最初に再度追加し、最後にある「;」を切り捨てます。

1行目:

awk 'BEGIN{RS="i-"}NF>1{print gensub("^(.*);$", "i-\\1", "g", gensub(/\n/,";","g"))}' sg1.txt

タスクを実行する方法はかなり複雑です。自分がしていることを次のように簡単に表現する方が自然です。

/^i-/ {
    if (line) print line;
    line=$0;
    next
}
{
    line = line";"$0
}
END {
    if (line) print line
}

^i-のある行を表示したら、古い状態を印刷して新しい行を開始してください。残りは追加します。すすぎ、繰り返します。最後に印刷することを忘れないでください。

初めてテストして印刷します。最後に、空のファイルが表示される場合に備えてテストして印刷してください。

答え4

端末を使用して各レコード(行)を印刷します;。ただし、行がaで始まらない限り、この場合はi-次のように印刷されます。

$ awk -vORS=\; '/^i-/{printf "%s%s,",a,$0 ; a="\n";next}1;END{printf "\n"}' file

i-095erwr244r22cfeaa,TF-CLIENT;TF-StKML2;
i-0c23232ac153534c5d,TF-CLIENT;TF-COMMON;TF-STEERR;
i-043434e0934347eb5,TF-CLIENT;TF-ADFS;TF-COMMON;TF-STCLUSTER_1;TF-SwewCLUSTER3;

関連情報