쉘에서 다른 컬럼으로 구성된 컬럼 그룹 출력

쉘에서 다른 컬럼으로 구성된 컬럼 그룹 출력

미리 감사드립니다!

다음과 같은 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

입력의 필드가 여러 공백(일종의 "예쁜 인쇄된 테이블" 형식)으로 구분되어 있고 두 번째 필드의 항목을 다른 두 필드를 기반으로 공백으로 구분된 목록으로 축소하려고 한다고 가정합니다.

$ 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.

관련 정보