Como processar correspondências de linha awk?

3

Eu tenho um arquivo com algumas linhas de dados que eu quero extrair. Eu estou pensando awk é um bom ajuste para isso. No pseudocódigo, estou imaginando fazer algo como:

  1. Encontrar correspondência para a linha que quero processar com awk
  2. Na segunda parte, dentro do {} encontre uma correspondência de expressão regular para meus dados, talvez com grep -o ?
  3. Imprima a correspondência, talvez no final, dentro do {} ou dentro e END

Não sei como fazer isso, sei que não estou usando cut corretamente, mas mostrei para dar uma idéia da intenção. Adoraria alguma ajuda. Essencialmente, quero colocar minhas mãos no $0 e começar a extrair várias correspondências de regex para que eu possa juntá-las em meu próprio formato CSV.

Isso é o que eu tentei:

➜  tmp cat data.txt
Concurrency Level:      1
Time taken for tests:   0.004 seconds
Complete requests:      1
Failed requests:        0
Total transferred:      838 bytes
HTML transferred:       632 bytes
Requests per second:    257.40 [#/sec] (mean)
Time per request:       3.885 [ms] (mean)
Time per request:       3.885 [ms] (mean, across all concurrent requests)
Transfer rate:          210.65 [Kbytes/sec] received
➜  tmp cat data.txt | awk '/Complete requests:/ {print;}'
Complete requests:      1
➜  tmp cat data.txt | awk '/Complete requests:/ {print $0;}'
Complete requests:      1
➜  tmp cat data.txt | awk '/Complete requests:/ {print;}'|cut -d: -f2
      1

Eu estou indo para algo como

Time taken for tests, 0.0004, s 
Requests per second (mean), 257.40, #/sec
.
.
.
Transfer rate received, 210.65, Kbytes/sec

Como os dados não são muito uniformes, é por isso que eu quero escrever um processamento separado "correspondência pós-regex" de $0 para cada correspondência /Concurrency Level:/ , Time taken for tests: , etc

    
por mbigras 06.10.2016 / 10:14

3 respostas

1

Você pode ter quantos pares de ação de regra awk desejar. Já que você parece querer reordenar alguns dos subcampos, você provavelmente quer uma regra global que divida tudo após o : em uma matriz que você possa manipular posteriormente por regra.

Por exemplo (mostrei apenas os dois primeiros aqui):

awk '
BEGIN {FS=":[ \t]+"; OFS=", "}
{split($2, a, /[ \t]+/)}
#
# now the case-by-case rule-action pairs
/Time taken/ {print $1, a[1], a[2]}
/Requests per second/ {print $1" "a[3], a[1], substr(a[2], 2, length(a[2])-2)}
' data.txt
Time taken for tests, 0.004, seconds
Requests per second (mean), 257.40, #/sec
    
por 06.10.2016 / 14:40
1

Eu também não estou certo de que entendi o que você precisa, mas acho que eu faria isso de uma só vez com algo como esse ...

awk '/Time|Requests|Transfer/{print $0}' data.txt

Desta forma, você pode carregar os padrões para combinar e usar o "|". Então, /Time|Requests|Transfer/ significa "Tempo de Jogo ou Solicitações ou Transferências" e imprime a linha

    
por 06.10.2016 / 10:51
0

Usando TXR :

@(repeat)
@  (cases)
@param: @val [@units] (@rawdesc)
@  (or)
@param: @val [@units] @rawdesc
@  (or)
@param: @val [@units]
@    (bind rawdesc nil)
@  (or)
@param: @val @units (@rawdesc)
@  (or)
@param: @val @units @rawdesc
@  (or)
@param: @val @units
@    (bind rawdesc nil)
@  (or)
@param: @val
@    (bind units "")
@    (bind rawdesc nil)
@  (end)
@  (bind desc @(if rawdesc ' (@(regsub #/,/ "" rawdesc))' ""))
@  (output)
@param@desc, @val, @units
@  (end)
@(end)

Executar:

$ txr tocsv.txr data.txt 
Concurrency Level, 1, 
Time taken for tests, 0.004, seconds
Complete requests, 1, 
Failed requests, 0, 
Total transferred, 838, bytes
HTML transferred, 632, bytes
Requests per second (mean), 257.40, #/sec
Time per request (mean), 3.885, ms
Time per request (mean across all concurrent requests), 3.885, ms
Transfer rate (received), 210.65, Kbytes/sec

Embora pareça detalhado devido à "escada" dos casos, eles eram fáceis de serem copiados e colados. O código produziu os resultados desejados na primeira tentativa e é transparente para entender: de relance, você obtém a imagem do que está procurando.

A ordem dos casos é significativa. Se o caso começar com a partida

@param: @val

foram colocados primeiro, val consumiria todo o valor depois dos dois pontos e espaços.

    
por 06.10.2016 / 14:18