重複した行をマージし、最後に「N / A」を追加します。

重複した行をマージし、最後に「N / A」を追加します。

テキストファイルには次の行があります。重複した行をマージし、必要に応じて行の末尾に「N / A」を追加して、各行に6つの列があるようにしたいと思います。

302C21;tSMe
S123C;1.17
302C21;2;346;SM-1-3/SM-1-4
SIEV1;tSMe
S123C;3;2225;20225
SIEV1;1;3;SM-1-1/SM-1-2;5

OUTPUT

SIEV1;tSMe;1;3;SM-1-2;5
302C21;tSMe;2;346;SM-1-3/SM-1-4;N/A
S123C;3;2225;20225;1.17;N/A

答え1

{   nl   -s\; -w1 -ba    | 
    sort -t\; -k2,2      | 
    sed  -e:n -e'h;$!N'  \
         -e's/^\([^;]*\(;[^;]*;\).*\)\n[^;]*\2/\1;/;tn' \
         -ex  -e:N       \
         -e's/;/;/6p;tD' \
         -e's|$|;N/A|;tN'\
         -e:D -ex -eD    |
    sort -t\; -nk1,1     |
    cut  -d\; -f2-;    
}   <in >out

だから巨大なパイプラインがあります。仕組みは次のとおりです。

  1. nlすべての入力行は、行番号の後に挿入された-sセミコロン区切り文字列を使用して番号付けされます;
  2. sort;入力の2cdセミコロンで区切られたフィールドをソートします。これが最初のフィールドです。
  3. sed入力行を同じ最初のフィールドと再帰的にマージし、文字列を再帰的に追加します。;N/A6つ以上のフィールドがあるまで各行の最後に移動します。
  4. sort最初のフィールドを並べ替えます。今回は、数値でnl入力を元の計算順序に並べ替えます。
  5. cutで最初に挿入した行番号と区切り文字を削除しますnl

出力:

302C21;tSMe;2;346;SM-1-3/SM-1-4;N/A
S123C;1.17;3;2225;20225;N/A
SIEV1;tSMe;1;3;SM-1-1/SM-1-2;5

この結果はあなたの結果とは異なります。並べ替えが逆のようですが、そうではありません。あなたが探しているものが何であるか明確に言わない限り、それはすべてです。

PS私はこのように書いています。すべて1行につながるかどうかは関係ありません。したがって、すべての改行と古いバックスラッシュを削除して1行にすることができます。

このように:

{ nl -s\; -w1 -ba | sort -t\; -k2,2 | sed -e:n -e'h;$!N' -e's/^\([^;]*\(;[^;]*\;).*\)\n[^;]*\2/\1;/;tn' -ex -e:N -e's/;/;/6p;tD' -e's|$|;N/A|;tN' -e:D -ex -eD | sort -t\; -nk1,1 | cut -d\; -f2-; } <in >out

なぜこのようなことをしたのか想像できません。

関連情報