シェルから別の列で構成される列グループの出力

シェルから別の列で構成される列グループの出力

よろしくお願いします!

次の3つの列を持つファイルがあります。

serv1   red     group1
serv1   black   group1
serv1   orange  group1
serv1   red     group2
serv1   orange  group2
serv1   red     group3
serv1   black   group3
serv1   orange  group3
serv2   orange  group1
serv2   red     group2
serv2   orange  group2
serv2   red     group3
serv2   black   group3
serv2   orange  group3
serv3   orange  group1
serv3   red     group1

私はそれを次のように見せます:

serv1   group1  red black   orange
serv1   group2  red orange
serv1   group3  red black   orange
serv2   group1  orange
serv2   group2  red orange
serv2   group3  red black   orange
serv3   group1  orange  red

最初のコードと次のコードでグループ化しようとすると問題はありませんが、複数のコードをグループ化することはできません。

awk '{ V_GRUPO[$1]= (V_GRUPO[$1]==""?"":V_GRUPO[$1] OFS) $2 }END  { for(x in V_GRUPO) print x, V_GRUPO[x] }' file.txt
serv1   red black   orange red  orange  red black   orange
serv2   orange  red orange  red black   orange
serv3   orange  red

¿どうしたの? ? ?

ありがとうございます! !

答え1

入力のフィールドが複数の空白(ある種の「きれいな印刷テーブル」形式)に分割されており、2番目のフィールドの項目を他の2つのフィールドに基づいてスペースで区切られたリストに縮小したいとします。

$ mlr --pprint -N nest --ivar ' ' -f 2 then reorder -f 1,3,2 file
serv1 group1 red black orange
serv1 group2 red orange
serv1 group3 red black orange
serv2 group1 orange
serv2 group2 red orange
serv2 group3 red black orange
serv3 group1 orange red

これは、以下を使用して元のフィールドを縮小して並べ替えます。ミラーmlr)。

データがタブで区切られ(TSV)、タブで区切られた出力が必要な場合--pprintに変更します--tsv。折りたたまれたデータのリストに別の区切り文字を必要--ivar ' 'に応じて変更します(例--ivar ';':使用;)。

たとえば、タブで区切られた入力と出力の場合は、;リスト区切り記号として使用します。

$ mlr --tsv -N nest --ivar ';' -f 2 then reorder -f 1,3,2 file
serv1   group1  red;black;orange
serv1   group2  red;orange
serv1   group3  red;black;orange
serv2   group1  orange
serv2   group2  red;orange
serv2   group3  red;black;orange
serv3   group1  orange;red

TSV入力を読み取り、各フィールドにラベルを追加し、数値フィールドの代わりに対応するラベルを使用し、素敵に印刷された表形式の出力を生成する別の例:

$ mlr --itsv --implicit-csv-header --opprint --barred label Server,Colour,Group then nest --ivar ';' -f Colour then reorder -f Server,Group,Colour file
+--------+--------+------------------+
| Server | Group  | Colour           |
+--------+--------+------------------+
| serv1  | group1 | red;black;orange |
| serv1  | group2 | red;orange       |
| serv1  | group3 | red;black;orange |
| serv2  | group1 | orange           |
| serv2  | group2 | red;orange       |
| serv2  | group3 | red;black;orange |
| serv3  | group1 | orange;red       |
+--------+--------+------------------+

答え2

使用スクリプト、スクリプト file.awk:

{
    k = $1 OFS $3
    a[k] = (k in a ? a[k] OFS : "" ) $2
}
END{
    for(key in a){
        print key, a[key]
    }
}

次に、次を実行します。

awk -f script-file.awk input
  • a[k]キーを使用する配列です。k = $1 OFS $3
  • OFS出力フィールドの区切り記号。
  • ?条件式(test ? true : false)です。
  • for(key in a)各キー

これは整列しない可能性があるため、整列が必要な場合はパイプを使用してください。

awk -f script-file.awk input | sort

答え3

入力は2つのキーフィールドにソートされるため、awkを使用すると、一度に1つのキーペア値のみがメモリに保存されます。

$ awk '
    { key = $1 OFS $3 }
    key != prev { if (NR>1) print vals; prev=vals=key }
    { vals = vals OFS $2 }
    END { print vals }
' file
serv1 group1 red black orange
serv1 group2 red orange
serv1 group3 red black orange
serv2 group1 orange
serv2 group2 red orange
serv2 group3 red black orange
serv3 group1 orange red

実際の入力がサンプル入力に従ってまだソートされていない場合は、まずソートしてください。

sort -b -k1,1 -k3,3 file | awk '...'

答え4

datamash列グループを折りたたむには、別の列(または別の列)を使用してください。

$ datamash -sW groupby 1,3 collapse 2 --collapse-delimiter ' ' <file

折りたたみ区切り線のマニュアル:

--collapse-delimiter=x
-c x
Use character X instead of comma to delimit items in a ‘collapse’ or ‘unique’ (aka ‘uniq’) list.

関連情報