Я думаю, нам следует сначала взглянуть на базовую структуру программы awk, шаблон {действие}. Основная операция заключается в сканировании текста построчно, поиске строк, соответствующих шаблону, а затем выполнении соответствующего действия. заканчивается после прочтения всех строк.
Давайте сначала рассмотрим самый простой пример: файл трассировки.log содержит имя, возраст и стаж работы.
звезда 25 1
луна 32 5
солнце 29 3
река 27 4
озеро 30 6
море 35 8
Теперь вы хотите найти сотрудников (вся строка), которые проработали не менее 5 лет. Это можно сделать одним предложением. Напишите нужное вам выражение непосредственно в части шаблона. Для идентификации всей строки используется $0.
awk '$3 >= 5 {print $0}' trace.log
1
результат:
луна 32 5
озеро 30 6
море 35 8
Если вы хотите добавить к выводу номер строки, это не так уж и много: Awk предоставляет встроенную переменную NR.
awk '$3 >= 5 {print NR,$0}' trace.log
1
результат:
2 луна 32 5
5 озеро 30 6
6 море 35 8
Если вы хотите использовать printf для форматирования вывода, это ваше личное дело.
awk '$3 >= 5 {printf("name: %s,age: %d \n",$1,$2)}' trace.log
1
Результат Цзян Цзы:
имя: Луна, возраст: 32
имя: озеро, возраст: 30
имя: море, возраст: 35
Обычно awk использует действие только для вывода нужных вам сегментированных данных. На самом деле красота заключается в шаблоне. Вы хотите видеть только те данные, имя которых — «луна».
awk '$1 == "moon"' trace.log # moon 32 5
1
образец можно объединить с помощью круглых скобок, && или ||, но не !
awk '$2 >30 && $3 >= 8' trace.log # sea 35 8
1
Сказав так много, все равно не интересно. Возможно, статистика будет вам полезна. Прежде всего, вам нужно понять два момента: ключевое слово END используется для соответствия позиции после последней строки. Вы можете создать свою собственные переменные для расчета, но не требуют указания. Хотите посмотреть, сколько людей проработало более 5 лет?
awk '$3 >= 5 {total += 1} END {print "超过5年:",total,"人"}' trace.log
1
Сканирование построчно похоже на цикл.Во время цикла вы можете начать выполнение (вычисление), END соответствует последней строке, а затем выполнить некоторые действия.
Теперь, когда вы умеете суммировать, хотите увидеть средний возраст сотрудников, не забывайте, что NR записывает количество строк.
awk '{total += $2} END {print total/NR}' trace.log
1.
Если вы хотите увидеть общий возрастной уровень (возможно, медиана более репрезентативна), вам следует сначала отсортировать
awk '{print $2," ", $3," " $1}' trace.log | sort
1.
Затем найдите данные в средней позиции и все будет ок.
awk '{print $2," ", $3," " $1}' trace.log | sort | awk '{line[NR] = $1} END {print line[int(NR/2)]}'
1.
Вы также хотите увидеть максимальное и минимальное значения возраста. Учитывая вышеизложенный опыт, не будьте слишком строгими.
awk '{print $2," ", $3," " $1}' trace.log | sort | awk '{line[NR] = $0} END {print line[1],"\n",line[NR]}'
Еще есть не упомянутое ключевое слово BEGIN, похожее на END. Не буду вдаваться в подробности. Для подведения итогов нарисуем картинку: