필드와 관련된 모든 데이터 인쇄

필드와 관련된 모든 데이터 인쇄

다음 파일을 고려하십시오.

foo,5
foo,7
foo,9
boo,5
boo,10
boo,10

내가 원하는 것은 $2레코드와 관련된 모든 데이터를 인쇄하는 것입니다.$1

이 예에서 원하는 출력은 다음과 같습니다.

foo,5,7,9
boo,5,10

답변1

해결책 awk:

awk 'BEGIN{OFS=FS=","}!(($1,$2)in c){c[$1,$2]=1;r[$1]=r[$1] OFS $2}
            END{for(i in r){print i r[i]}}' file
  1. OFS=FS일관성으로 설정합니다 .
  2. 사용awk다차원 배열$2지금까지 마주한 가치를 기억해 보세요 . 일치하는 항목이 없는 경우에만 "계속"( )하십시오 !(($1,$2)in c).
  3. 새 키가 처음 발견되면 다차원 배열에 "더미" 값을 제공합니다.
  4. 편의를 위해 원하는 출력 문자열을 다른 배열로 연결합니다.
  5. 에서 END루프를 인쇄합니다.
    • 루프 반복은 특정 순서가 아니며 awk필요한 경우 정렬 기능을 사용할 수 있습니다.

답변2

데이터를 "해시", "연관 배열", "딕셔너리" 또는 무엇으로 부르든 구문 분석합니다.

perl -F, -lane '$first{$F[0]}->{$F[1]} = (); END { print join(",", $_, sort { $a <=> $b } keys %{ $first{$_} } ) for keys %first }' < inputfile

답변3

Bash에서 awk가 없는 솔루션:

$ cat bla.txt 
foo,5
foo,7
foo,9
boo,5
boo,10
boo,10

$ { buffer="";
  while read i ; do
    key="${i%,*}" ;
    if [[ "$key" == "$oldkey" ]] ; then
      idx="${i#*,}";
      if [[ ! "$idx" == "$oidx" ]] ; then
        buffer+=",$idx" ;
        oidx="$idx";
      fi ;
    else
      test -z $buffer || echo $buffer ;
      oldkey="$key" ;
      buffer="$i" ;
      oidx="${i#*,}" ;
    fi ;
  done ; echo $buffer ; } < bla.txt
foo,5,7,9
boo,5,10
$

예쁘거나 짧지는 않지만 작동합니다. 나는 또한 awk 솔루션을 보는 데 관심이 있습니다.

답변4

그리고gnu datamash:

datamash -t ',' -s -g 1 unique 2 <infile

출력 값의 순서는 처리 전에 정렬되기 때문에 다릅니다.

boo,10,5
foo,5,7,9

관련 정보