Ajuda para decifrar este script AWK

0
xev | awk -F'[ )]+' '/^KeyPress/ { a[NR+2] } NR in a { printf "%-3s %s\n", %5, %8}

Quando eu uso o xev, há apenas um pouco de informação que eu quero. A resposta natural do uso do xev para obter informações de código-chave é assim ...

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

O resultado do script AWK só retornará:

40 d

Isso me fez querer aprender AWK:)

Então, depois de aprender sobre NR e fazer alguns tutoriais, agora estou tentando descobrir isso. Primeiro o -F é apenas divide por campos neste caso '[)] +' Eu acho que isso é regex para 1 ou mais espaços ou parênteses de fechamento. Eu não entendo isso. Eu não vejo espaços antes do pré-teste. Além disso, não sei o que um espaço em uma caixa de regex faz aqui, porque eu só aprendi sobre ferramentas de espaço em branco como \ s. Então, eu queria ver quais campos estavam com $ 5 e% 8 porque não pareciam corretos em minha análise e fiquei confuso !!

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

edite: Então, o que é isso printf "%-3s %s\n", $5, $8} ? Por que a saída é tão diferente do meu exemplo de eco acima?

Obviamente, isso vem da mágica de {a[NR+2] NR in a} . Algum tipo de array e um loop for.

Eu olho para o NR + 2 e isso me faz pensar: desde quando o AWK começa o NR começa em 1 e adicionar 2 seria a terceira linha. Isso parece certo, já que todas as informações que eu quero estão na terceira linha.

O que está acontecendo com um [NR + 2]? para NR em um printf ...? Eu entendo printf eu entendo por loops. O modo como o NR é usado aqui me deixa perplexo.

Eu acho que a verdadeira questão é o que está acontecendo com 'a'? Isso é uma coisa predefinida que eu não conheço?

    
por Michael Bruce 25.08.2016 / 21:43

3 respostas

1

Você parece ter deduzido corretamente o que {a[NR+2]} NR in a { ... }} faz;

  • /^KeyPress/ {a[NR+2]} cria um elemento (valor vazio) na matriz a com índice NR+2 , quando o início da linha NR corresponde à sequência KeyPress
  • Por isso, NR in a é verdadeiro para a linha duas linhas abaixo, em que /^KeyPress/ correspondia

A esse respeito, talvez pudesse ter sido escrito de forma mais transparente como

awk -F'[ )]+' '/^KeyPress/ {n=NR+2} NR==n { printf "%-3s %s\n", $5, $8}'

Uma pergunta possivelmente mais complicada é por que os campos a serem impressos são $5 e $8 em vez de $4 e $7 ; isso é porque o tratamento do espaço em branco inicial é diferente quando se usa um separador de campo não padrão: a partir do Divisão de Campos Padrão seção do manual GNU awk :

Fields are normally separated by whitespace sequences (spaces, TABs, and newlines), not by single spaces. Two spaces in a row do not delimit an empty field. The default value of the field separator FS is a string containing a single space, " ". If awk interpreted this value in the usual way, each space character would separate fields, so two spaces in a row would make an empty field between them. The reason this does not happen is that a single space as the value of FS is a special case—it is taken to specify the default manner of delimiting fields.

If FS is any other single character, such as ",", then each occurrence of that character separates two fields. Two consecutive occurrences delimit an empty field. If the character occurs at the beginning or the end of the line, that too delimits an empty field. The space character is the only single character that does not follow these rules.

    
por 25.08.2016 / 23:10
0

%-3s significa imprimir uma string em um campo com 3 caracteres de largura, com espaços de preenchimento à direita e não à esquerda. Então vai imprimir

40  d

em vez de

 40 d
    
por 25.08.2016 / 22:07
0

Eu posso ajudar um pouco, mas alguém aqui deve ser capaz de fornecer uma resposta mais detalhada. Mas vamos acabar com isso.

Primeiro, você está enviando a saída do xev para o awk com o |

Você está certo de que -F está definindo o caractere separador de coluna para Awk, e a expressão regular para corresponder ao caractere é [)] +

corresponderá apenas uma vez na saída de amostra que você forneceu. Tudo depois disso é o script awk.

/ ^ KeyPress / é outra expressão regular, procurando por uma nova linha começando com "KeyPress" ... o que parece redundante.

Os argumentos para printf são separados por vírgulas, sendo o primeiro a formatação, portanto: "% -3s% s \ n" é a formatação. Consulte e aqui

É possível que {printf "% -3s% s \ n",% 5,% 8} seja {printf "% -3s% s \ n", $ 5, $ 8}?

Eu não consigo entender isso. Espero que alguém possa decodificá-lo! BTW - você pode usar este para ajudar a testar o regex.

    
por 25.08.2016 / 22:32