xev | awk -F'[ )]+' '/^KeyPress/ { a[NR+2] } NR in a { printf "%-3s %s\n", %5, %8}
Когда я использую xev, мне нужен только определенный бит информации. Естественная реакция использования xev для получения информации о коде ключей выглядит так ...
KeyPress event, serial 48, synthetic NO, window 0x1600001,
root 0xf6, subw 0x0, time 754405, (348,566), root:(349,620),
state 0x0, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (64) "d"
XmbLookupString gives 1 bytes: (64) "d"
XFilterEvent returns: False
KeyRelease event, serial 48, synthetic NO, window 0x1600001,
root 0xf6, subw 0x0, time 754488, (348,566), root:(349,620),
state 0x0, keycode 40 (keysym 0x64, d), same_screen YES,
XLookupString gives 1 bytes: (64) "d"
XFilterEvent returns: False
Результатом сценария AWK будет только возврат:
40 d
Это заставило меня захотеть изучить AWK :)
Итак, после изучения NR и делая несколько уроков, я сейчас пытаюсь понять это. Сначала -F просто делится на поля, в этом случае '[)] +' Я думаю, что это регулярное выражение для 1 или более пробелов или закрывающих скобок. Я этого не понимаю. Я не вижу пробелов перед претензией. Кроме того, я не знаю, что здесь делает пробел в поле регулярного выражения, потому что я узнал только о таких инструментах, как \ s.Поэтому я хотел посмотреть, какие поля отображаются с $ 5 и% 8, потому что в моем анализе это выглядело неправильно, и я был сбит с толку !!
echo "state 0x0, keycode 12 (keysym 0x33, 3), same_screen YES," | awk '{print $8}'
same_screen
echo "state 0x0, keycode 12 (keysym 0x33, 3), same_screen YES," | awk '{print $5}'
(keysym
редактировать:
Так что это printf "% -3s% s \ n", $ 5, $ 8}
??
Почему результат так отличается от моего эхо-примера выше?
Очевидно, это происходит из-за магии {a [NR + 2] NR в a}
. Какой-то массив и цикл for.
Я смотрю на NR + 2, и это заставляет меня задуматься: поскольку, когда AWK запускается, NR начинается с 1, и добавление 2 сделает его третьей строкой. Это выглядит правильно, поскольку вся необходимая мне информация находится в третьей строке.
Что происходит с [NR + 2]? для НР в принтф ...? Я понимаю, что printf я понимаю для циклов. То, как здесь используется NR, сбивает меня с толку.
Думаю, настоящий вопрос в том, что происходит с «а»? Я не знаю об этом заранее?
Похоже, вы правильно поняли, что делает {[NR + 2]} NR в {...}}
;
/ ^ KeyPress / {a [NR + 2]}
создает элемент (с пустыми значениями) в массиве a
с индексом NR + 2
, когда начало строка NR
соответствует строке KeyPress
NR в
, следовательно, верно для строки двумя строками ниже, где совпали / ^ KeyPress /
В этом уважение, возможно, это можно было бы записать более прозрачно как
awk -F'[ )]+' '/^KeyPress/ {n=NR+2} NR==n { printf "%-3s %s\n", $5, $8}'
Возможно, более сложный вопрос заключается в том, почему поля, которые должны быть напечатаны, составляют $ 5
и $ 8
, а не $ 4
] и 7 долларов
; это потому, что обработка начальных пробелов отличается при использовании разделителя полей, отличного от значения по умолчанию: из раздела Разделение полей по умолчанию руководства GNU awk
:
Поля обычно разделяются последовательности пробелов (пробелы, табуляции, и символы новой строки), а не одиночные пробелы. Два пробела подряд не ограничивают пустое поле . Значение по умолчанию разделителя полей FS - это строка, содержащая один пробел "". Если бы awk интерпретировал это значение обычным образом, каждый пробел разделял бы поля, поэтому два пробела в строке образовывали бы пустое поле между ними. Причина, по которой этого не происходит, заключается в том, что одиночный пробел в качестве значения FS является особым случаем - он используется для определения способа разграничения полей по умолчанию.
Если FS - любой другой одиночный символ, например ",", то каждое вхождение этого символа разделяет два поля.Два последовательных вхождения ограничивают пустое поле. Если символ встречается в начале или конце строки, это тоже ограничивает пустое поле. Пробел - единственный одиночный символ, который не соответствует этим правилам .
%-3s
означает печать строки в поле шириной 3 символа, с пробелами справа, а не слева. Таким образом, будет выведено
40 d
а не
40 d
Я могу немного помочь, но кто-то здесь должен уметь чтобы дать более подробный ответ. Но давайте разберемся.
Во-первых, вы передаете вывод xev в awk с помощью |
Вы правы, что -F определяет символ разделителя столбцов для Awk, а регулярное выражение для соответствия этому символу - [)] +
он будет соответствовать только один раз в предоставленном вами образце выходных данных. Все, что после этого, - это сценарий awk.
/ ^ KeyPress / - еще одно регулярное выражение, ищущее новую строку, начинающуюся с «KeyPress» ... что кажется избыточным.
Аргументы для printf разделяются запятыми, причем первый - форматирование, поэтому: "% -3s% s \ n" - это форматирование. См. И здесь
Возможно ли, что {printf "% -3s% s \ n",% 5,% 8} означает {printf "% -3s% s \ n", $ 5, $ 8 }?
Я не совсем понимаю это. Надеюсь, кто-нибудь еще сможет его расшифровать! Кстати, вы можете использовать this для проверки регулярного выражения.