awk 인쇄 명령에서 정렬을 사용하는 방법은 무엇입니까?


8

내가 쓰고있는 awk 스크립트에 몇 가지 명령이 있습니다.

print "Here are some players and their numbers, sorted by last name"
if(sum[x] > 500) {print x, $2}

어떤 출력 :

Here are some players and their numbers, sorted by last name
Lebron James 23
Kevin Durant 35
Kobe Bryant 24
Blake Griffin 32
Dikembe Mutumbo 55

awk 스크립트에서sort 명령 사용 하여 플레이어와 숫자 만 정렬하려면 어떻게해야합니까?


3
답변에 대한 귀하의 의견을 감안할 때 귀하의 질문에 awkshell 스크립트 가 혼란스러워 보입니다 . 스크립트가 아닌 awk 스크립트 내 에서 정렬을 수행하려는 것 같습니다 . 맞다면 질문을 편집하고 두 개의 'shell'을 'awk'로 바꾸십시오. 예, AWK는 정렬 기능을 가지고 있지만, 아주 관여 : 별도의 노트에 당신이에서 추출해야합니다 자신의 두 번째 필드에 키가 배열의 모든 라인을 저장해야 다음 설정 난해한 값으로, 그런 다음 배열을 출력하십시오. 나는 거기에 가지 않을 것이다. xPROCINFO["sorted_in"]
zwets

1
내 말은 :의 단순성을 감안할 때 거기에 가지 않을 것입니다 ... | sort -k2,2.
zwets

@zwets ...| sort -k2,2인쇄해야 할 다른 줄이 있으면 어떻게 구현 합니까? 수정 된 질문을 확인하십시오.
KM142646

하여 echo쉘에서 헤더 행을 -ing, 다음 실행 awk | sort파이프 라인을.
zwets

답변:


12

당신은 | sort -k2당신의 명령에 추가 할 수 있습니다 . 두 번째 열을 기준으로 알파벳순으로 정렬됩니다.

예:

$ echo "Lebron James 23
Kevin Durant 35
Kobe Bryant 24
Blake Griffin 32
Dikembe Mutumbo 55" | sort -k2

결과

Kobe Bryant 24
Kevin Durant 35
Blake Griffin 32
Lebron James 23
Dikembe Mutumbo 55

불행히도 나는 스크립트를 사용하고 있으며 sort 명령은 다른 많은 출력과 뭉칠 것입니다. {print x, $2}스크립트 코드에서 직접 출력을 정렬하는 방법이 있습니까? 파이핑 할 때 오류가 발생했습니다 if(sum[x] > 500) {print x, $2} | sort -k2.
KM142646

3
@KMoy : if(sum[x] > 500) {print x, $2}는 Awk 코드이며 | sort -k2쉘 명령입니다. 분명히 다른 언어이기 때문에 두 가지를 혼합 할 수는 없습니다. 대신 sortAwk 코드 스 니펫을 실행하는 Awk 인터프리터의 출력에 명령 을 적용해야합니다 . 무슨 뜻인지 모른다면 질문을 확장하여 전체 그림을 보내주십시오.
David Foerster

1
쉘 스크립트를 작성하고 있습니까? 그런 다음 두 가지 옵션이 있습니다. 1. run ./my-script.sh | sort -k2. ``| 질문에 주어진 출력을 생성하는 스크립트 줄에 -k2`를 정렬하십시오.
Wayne_Yux

@Wayne_Yux 원래 질문에 대한 수정 사항을 확인하십시오.
KM142646

그렇다면 당신은 아마 @steeldriver의 답변이 필요합니다
Wayne_Yux

9

권장하지는 않지만 (외부 sort명령을 통해 결과를 파이핑하는 것이 상대적으로 간단 함 ) gawk를 사용하여 배열 값 및 인덱스 정렬에 설명 된 것처럼 최신 GNU awk (최소 4.0 IIRC) 로이 작업을 수행 할 수 있습니다

인덱스가 인 연관 배열에 데이터가 있다고 가정하고 구현하는 방법은 다음과 같습니다 Firstname Lastname. 먼저 인덱스를 분할하고 Lastname( Firstname예 : 타이 브레이커로) 먼저 비교하는 사용자 정의 비교 함수를 정의해야합니다.

function mycmp(ia, va, ib, vb, sa, sb) {
  if(split(toupper(ia), sa) && split(toupper(ib), sb)) {
    if(sa[2] < sb[2]) return -1;
    else if (sa[2] > sb[2]) return 1;
    else {
      # compare first names
      if(sa[1] < sb[1]) return -1;
      else if (sa[1] > sb[1]) return 1;
      else return 0;
    }
  }
  else return 0;
}

이제 PROCINFO["sorted_in"]@zwets의 의견에 언급 된 배열 정렬 방법을 사용할 수 있습니다

PROCINFO["sorted_in"] = "mycmp";
for(i in a) print i, a[i];

함께 모으기

#!/usr/bin/gawk -f

function mycmp(ia, va, ib, vb, sa, sb) {
  if(split(toupper(ia), sa) && split(toupper(ib), sb)) {
    if(sa[2] < sb[2]) return -1;
    else if (sa[2] > sb[2]) return 1;
    else {
      # compare first names
      if(sa[1] < sb[1]) return -1;
      else if (sa[1] > sb[1]) return 1;
      else return 0;
    }
  }
  else return 0;
}

{
  a[$1" "$2] = $3;
}

END {
  PROCINFO["sorted_in"] = "mycmp";
  for(i in a) print i, a[i];
}

테스트 :

$ ./namesort.awk yourfile
Kobe Bryant 24
Kevin Durant 35
Blake Griffin 32
Lebron James 23
Dikembe Mutumbo 55

awk의 더 작거나 오래된 버전의 경우 가장 좋은 방법은 인덱싱 된 데이터를 Lastname Firstname대신 저장 하고 기존의 정렬 방식으로 정렬 asorti한 다음 배열을 통과하여 인덱스 필드를 분할하고 스왑하여 인쇄하는 것입니다.

awk '
  {a[$2" "$1]=$3} 
  END {
    n=asorti(a,b); for (i=1;i<=n;i++) {split(b[i],s); print s[2], s[1], a[b[i]]}
}' yourfile

5

sort단지 공백에 의해이 두 번째 필드를 구분하여 사용 키 -k2,2:

... | sort -k2,2

기본적으로 sort사전 식으로 정렬합니다.

정렬 키의 마지막 필드를 언급하지 않으면 (즉, 그냥 사용 -k2하는 경우) 두 번째로 시작 sort하는 모든 필드 에 따라 원하는 결과를 얻지 못할 수 있습니다 .

또한 확인하십시오 man sort.


내가 필요한 웨인의 게시물에 코멘트를 확인하시기 바랍니다
KM142646

1

시험

awk -f myscript.awk | sort -k2

myscript.awk에는 순전히 awk 명령이 들어 있습니다.

실제 스크립트가 쉘 스크립트 인 경우 다음과 같은 여러 옵션이 있습니다.

  • 정렬을 통한 파이프 출력. ./myscript.bash | sort -k2

  • 대신 스크립트 내에서 코드를 함수로 다시 작성

    $ cat t1
    #!/bin/bash
    for i in 2 4 3 1 5;
    do
      echo $i
    done
    
    $ ./t1
    2
    4
    3
    1
    5
    

    하다

    $ cat t2
    #!/bin/bash
    function foo {
      for i in 2 4 3 1 5;
      do
        echo $i
      done
    }
    foo | sort
    
    $ ./t2
    1
    2
    3
    4
    5
    

그러나 함수를 만드는 대신 do ... done 구조에 정렬을 적용 할 수도 있습니다.

    do
       echo $i
    done | sort

왜 함수를 정의합니까?
zwets

@zwets를 사용하면 루핑 제어 구조를 포함한 임의의 코드 결과를 파이프 라인을 통해보다 쉽게 ​​공급할 수 있습니다. 불필요한 경우가 있지만 유용한 일반적인 패턴을 찾습니다. 이것을 설명하기 위해 답변을 편집하겠습니다.
RedGrittyBrick

1

인쇄 할 데이터를 정렬하려면 :

  • 두 번째 필드 (공백으로 구분)를 인쇄한다고 가정하면 다음을 사용하십시오.

    awk '{print $2}' data.txt | sort
    

    예 :

    $cat>data.txt
    1 Kedar 20
    2 Amit 30
    3 Rahul 21
    ^C
    
    $awk '{print $2}' | sort
    Amit
    Kedar
    Rahul
    
  • 전체를 인쇄하고 data.txt2 열에 정렬하려면 다음을 수행하십시오.

    $awk '{print}'|sort -k2
    2 Amit 30
    1 Kedar 20
    3 Rahul 21
    

요구 사항에이 논리를 사용하십시오.

man sort더 흥미로운 기능에 사용할 수 있습니다 sort.


0

아래는 어떻습니까 :

 awk 'BEGIN{str="1\n2\n3\n4"; system("echo -e \""str"\" | sort -r")}'

테스트 할 때 작동합니다.


0
print "Here are some players and their numbers, sorted by last name"
if(sum[x] > 500) {print x, $2 | "sort -k2,2"}

출력을 파일로 정렬하려면 다음을 수행하십시오.

print "Here are some players and their numbers, sorted by last name"
if(sum[x] > 500) {print x, $2 | "sort -k2,2 > sortedFile"}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.