Как использовать вид на awk команде печати?

У меня есть несколько команд в 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

Как я могу использовать sort команда в моем awk сценарии для сортировки плееров и их чисел ТОЛЬКО?

8
задан 31 October 2017 в 08:15

7 ответов

можно добавить | 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
11
ответ дан 16 November 2019 в 06:44

К sort только пробелом разделил второе поле, используйте ключ -k2,2:

... | sort -k2,2

значением по умолчанию sort делает сортировку лексикографически.

Примечание, что, если Вы не упоминаете последнее поле для ключа сортировки т.е. если Вы просто используете -k2 затем, Вы не могли бы получить желаемый результат, поскольку это будет sort согласно все поля запуск со второго.

Также проверка man sort.

5
ответ дан 16 November 2019 в 06:44

что относительно ниже:

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

это работает, когда я протестировал.

0
ответ дан 16 November 2019 в 06:44
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"}
0
ответ дан 16 November 2019 в 06:44

Хотя я не рекомендовал бы это (учитывая относительную простоту передачи по каналу результата через внешнее sort команда), можно сделать это, по крайней мере, с последними версиями 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
8
ответ дан 16 November 2019 в 06:44

Попробовать

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
       echo $i
    done | sort
1
ответ дан 16 November 2019 в 06:44

Отсортировать Ваши данные для печати:

  • Предположим, что Вы хотите распечатать 2-е поле (разделенный пробел) используют это:

    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.txt но отсортированный на столбце 2, затем:

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

Используйте эту логику (логики) в своем требовании.

Можно использовать man sort для более интересных функций sort.

1
ответ дан 16 November 2019 в 06:44

Другие вопросы по тегам:

Похожие вопросы: