Como subtrair linhas (linhas) com AWK

8

Estou tentando descobrir como posso usar o AWK para subtrair linhas. Por exemplo, imagine que o arquivo de entrada é:

30
20

A saída seria:

10

Agora, como teste, estou tentando calcular a coluna de memória "Usada" de:

$ cat /proc/meminfo

Então, no momento, escrevi isso:

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    -- Here comes the calculation using AWK

Eu tentei o seguinte:

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk '{$0-s}{s=$0} END {print s}' 

Mas isso só me dá a última linha de dados.

Encontrei uma solução de trabalho, mas duvido que seja a mais adequada. Toda a minha experiência de codificação me diz que codificar a quantidade de linhas é terrível: P

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | awk 'NR == 1{s=$0} NR == 2 {s=s-$0} END {print s}'
    
por Dylan Meeus 02.03.2014 / 17:32

3 respostas

9

Você também pode fazer isso usando awk , paste e bc . Eu acho essa abordagem mais fácil de lembrar, a sintaxe de awk sempre exige que eu procure as coisas para confirmar.

NOTA: Esta abordagem tem a vantagem de poder lidar com várias linhas de saída, subtraindo o segundo, terceiro, quarto, etc. números do primeiro.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}' | paste -sd- - | bc
7513404

Detalhes

O texto acima usa awk para selecionar a coluna que contém os números que queremos subtrair.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'
7969084
408432

Em seguida, usamos paste para combinar esses valores de 2 valores e adicionar o sinal de menos entre eles.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- -
7969084-346660

Quando passamos isso para bc , ele realiza o cálculo.

$ grep -P 'MemTotal|MemFree' /proc/meminfo | \
    awk '{print $2}'| paste -sd- - | bc
7513404
    
por 02.03.2014 / 17:55
3

A solução puramente estranha, sem comandos redundantes de gato ou grep:

awk '/MemTotal/ {TOT=$2} /MemFree/ {FREE=$2} END {printf("%d kB Used\n", TOT-FREE)}' /proc/meminfo

Eu vejo o awk_FTW vencê-lo, mas eu acho que a formatação da saída pode ser boa.

    
por 15.04.2014 / 14:51
2

Tente isto:

grep -P 'MemTotal|MemFree' /proc/meminfo | \
awk 'NR==1{s=$2;next}{s-=$2}END{print s}'
    
por 02.03.2014 / 17:36

Tags