У меня есть несколько команд в 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 сценарии для сортировки плееров и их чисел ТОЛЬКО?
можно добавить | 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
только пробелом разделил второе поле, используйте ключ -k2,2
:
... | sort -k2,2
значением по умолчанию sort
делает сортировку лексикографически.
Примечание, что, если Вы не упоминаете последнее поле для ключа сортировки т.е. если Вы просто используете -k2
затем, Вы не могли бы получить желаемый результат, поскольку это будет sort
согласно все поля запуск со второго.
Также проверка man sort
.
что относительно ниже:
awk 'BEGIN{str="1\n2\n3\n4"; system("echo -e \""str"\" | sort -r")}'
это работает, когда я протестировал.
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"}
Хотя я не рекомендовал бы это (учитывая относительную простоту передачи по каналу результата через внешнее 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
Попробовать
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
Отсортировать Ваши данные для печати:
Предположим, что Вы хотите распечатать 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
.