Расшифровка этого сценария AWK

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, сбивает меня с толку.

Думаю, настоящий вопрос в том, что происходит с «а»? Я не знаю об этом заранее?

0
12.05.2019, 14:10
3 ответа

Похоже, вы правильно поняли, что делает {[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 - любой другой одиночный символ, например ",", то каждое вхождение этого символа разделяет два поля.Два последовательных вхождения ограничивают пустое поле. Если символ встречается в начале или конце строки, это тоже ограничивает пустое поле. Пробел - единственный одиночный символ, который не соответствует этим правилам .

1
28.01.2020, 02:47

%-3s означает печать строки в поле шириной 3 символа, с пробелами справа, а не слева. Таким образом, будет выведено

40  d

а не

 40 d
0
28.01.2020, 02:47

Я могу немного помочь, но кто-то здесь должен уметь чтобы дать более подробный ответ. Но давайте разберемся.

Во-первых, вы передаете вывод xev в awk с помощью |

Вы правы, что -F определяет символ разделителя столбцов для Awk, а регулярное выражение для соответствия этому символу - [)] +

он будет соответствовать только один раз в предоставленном вами образце выходных данных. Все, что после этого, - это сценарий awk.

/ ^ KeyPress / - еще одно регулярное выражение, ищущее новую строку, начинающуюся с «KeyPress» ... что кажется избыточным.

Аргументы для printf разделяются запятыми, причем первый - форматирование, поэтому: "% -3s% s \ n" - это форматирование. См. И здесь

Возможно ли, что {printf "% -3s% s \ n",% 5,% 8} означает {printf "% -3s% s \ n", $ 5, $ 8 }?

Я не совсем понимаю это. Надеюсь, кто-нибудь еще сможет его расшифровать! Кстати, вы можете использовать this для проверки регулярного выражения.

0
28.01.2020, 02:47

Теги

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