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
답변에 대한 귀하의 의견을 감안할 때 귀하의 질문에 awk 및 shell 스크립트 가 혼란스러워 보입니다 . 쉘 스크립트가 아닌 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.