열별로 스크립트를 정렬하고 중복을 제거하는 방법

열별로 스크립트를 정렬하고 중복을 제거하는 방법

거의 2000줄의 파일이 있습니다. 파일 형식은 다음과 같습니다.

12 34
0 2
2 3
7 9
1 2
306 237
0 9
12 134
2 7
2 9
306 3
  

중복된 첫 번째 열을 제거하고 두 번째 열로 구성하는 bash 스크립트를 작성하려고 합니다. 나는 다음과 같은 결과를 기대합니다.

0 2 9 
1 2
2 3 7 9
7 9 
12 34 134
306 237 3

일부 코드를 시도했지만 원하는 결과를 얻지 못했습니다. 어떻게 이를 달성할 수 있으며 무엇을 사용해야 합니까?

답변1

중복 행을 사용 sortuniq제거한 다음 awk첫 번째 열 값으로 인덱싱된 배열을 사용한 다음 두 번째 열을 배열의 각 값에 추가할 수 있습니다. 다음과 같습니다.

sort test.txt | uniq | awk '{if(col[$1])col[$1]=col[$1]" "$2; else col[$1]=$2;}; END{for (i in col) print i, col[i]}'

test.txt입력 파일 입니다 .

올바른 값이 있는 배열에 새 열을 추가하기 전에 배열이 비어 있는지 확인해야 합니다. 값 사이에 공백을 추가하기만 하면 됩니다.

답변2

우리는 함께 awk할 수 있습니다:

awk '{ found[$1]= (found[$1]? found[$1] FS $2: $2); };
END  { for (x in found) print x, found[x]; }' infile

두 번째 열을 동일한 첫 번째 열과 연결하고 연관 배열에 저장한 후 이름을 으로 지정하겠습니다. 첫 번째 열을 인쇄하는 found동안 (우리는 이를 다음과 같이 사용합니다.END배열 키우리는 다음을 통해 접근할 것입니다.keyif x)라는 이름을 붙인 다음 두 번째 열이 결합됩니다(다음을 통해 액세스 가능).array_name[key])

답변3

사용 datamash:

$ datamash -s -t ' ' -g 1 collapse 2 <file
0 2,9
1 2
12 34,134
2 3,7,9
306 237,3
7 9

이렇게 하면 공백으로 구분된 데이터를 읽고 정렬한 다음 두 번째 열을 첫 번째 열에서 제공하는 그룹으로 축소합니다.

쉼표를 공백으로 바꾸려면 출력을 다음으로 전달하십시오 tr , ' '.

$ datamash -s -t ' ' -g 1 collapse 2 <file | tr , ' '
0 2 9
1 2
12 34 134
2 3 7 9
306 237 3
7 9

행을 숫자순으로 정렬하시겠습니까? 다음 주소로 전달하세요 sort -n.

$ datamash -s -t ' ' -g 1 collapse 2 <file | tr , ' ' | sort -n
0 2 9
1 2
2 3 7 9
7 9
12 34 134
306 237 3

또는 먼저 숫자 정렬을 수행한 다음 -s통화에서 제거합니다 datamash.

$ sort -n <file | datamash -t ' ' -g 1 collapse 2 | tr , ' '
0 2 9
1 2
2 3 7 9
7 9
12 134 34
306 237 3

각 행을 열별로 숫자로 정렬하려면(첫 번째 열 제외) 원본 데이터가 첫 번째 열뿐만 아니라 두 번째 열에서도 정렬되어 있는지 확인하세요.

$ sort -k 1,1n -k 2,2n <file | datamash -t ' ' -g 1 collapse 2 | tr , ' '
0 2 9
1 2
2 3 7 9
7 9
12 34 134
306 3 237

(출력의 마지막 두 줄에 나타나는 차이점에 유의하세요.)

답변4

파일의 두 필드를 숫자로 정렬하고 추가 처리를 위해 GNU awk/sed에 전달하면 원하는 o/p를 얻을 수 있습니다.

$ sort -n -k1 -k2 < file \
| awk '
    BEGIN { ORS = "" }
    prev != $1"" {
      if (NR>1) print RS
      print
      prev = $1
      next
    }{ print ORS, $2 }
    END { print RS }
' -

$ sort -n -k1 -k2 < file \
| sed -Ee '
  :a
  $!N
  /^(\S+)\s.*\n\1\s/s/\n\S+//
  ta
  P;D
'

산출:

0 2 9
1 2
2 3 7 9
7 9
12 34 134
306 3 237

관련 정보