“grep” o espaço disponível da saída “df”

2

Olá eu preciso grep a saída do df. Infelizmente o awk não é uma opção (mesmo que seja a opção mais fácil) aqui só posso usar o grep.

Filesystem           1K-blocks      Used Available Use% Mounted on
none                         4         0         4   0% /sys/fs/cgroup
none                      5120         0      5120   0% /run/lock
none                   1981488       444   1981044   0% /run/shm
none                    102400        64    102336   0% /run/user
/dev/sda3            418176236 281033024 137143212  67% /media/mark/7EE21FBAE21F761D

Então, por exemplo, eu quero a coluna de $ 4 da linha que começa com / dev / sda3

    
por twigg 25.09.2014 / 11:08

3 respostas

7

Se você tem uma versão do grep que suporta -P (regex compatível com perl, PCREs) e -o (imprime apenas a string correspondente), você pode fazer

df | grep -oP '/sda3.* \K\d+(?=\s+\d+%)' 

Explicação

Aqui, combinamos /sda3 , depois tantos caracteres quanto possível até encontrarmos um trecho de números ( \d+ ) que é seguido por um ou mais espaços ( \s+ ), então um ou mais números ( \d+ ) e um % . A construção foo(?=bar) é lookahead positivo e permite pesquisar a string foo apenas se é seguido pela string bar . O \K é um truque de PCRE que significa "descartar qualquer coisa que corresponda a esse ponto". Combinado com -o , permite usar strings que precedem seu padrão para ancorar sua correspondência, mas não imprimi-las.

Sem -P , as coisas são mais complicadas. Você precisaria de vários passes. Por exemplo:

df | grep -o '/sda3.*%' | grep -Eo '[0-9]+ *[0-9]+%' | grep -Eo '^[0-9]+'

Explicação

Aqui, o primeiro grep identifica a linha certa e imprime tudo até % . O segundo imprime o maior número de números antes de um espaço e outro trecho de números terminando com % e o final imprime o maior número de números encontrados no início da linha. Como o anterior apenas imprimiu o espaço livre e a porcentagem, este é o espaço livre.

Se o seu grep nem mesmo suportar -E , você poderia fazer:

df | grep -o '/sda3.*%' | grep -o '[0-9]* *[0-9]*%' | grep -o '[0-9][0-9]* '

Explicação

Aqui, não podemos usar + para "um ou mais", portanto, para o último grep , precisamos especificar pelo menos um número, seguido por 0 ou mais ( [0-9][0-9]* ).

Se você pode usar outras ferramentas, é claro que as coisas ficam mais fáceis:

df | sed -n '/sda3/{s/  */ /gp}' | cut -d' ' -f4

Explicação

O sed não imprime nada ( -n ), a menos que a linha atual corresponda a sda3 ( /sda3/{} ) e, em caso afirmativo, substitua todos os espaços consecutivos por um único, permitindo o uso de cut para imprimir o quarto campo.

Ou

df | perl -lne 'm#/sda3.+\s(\d+)\s+\d+%# && print $1' 

Explicação

O -l adiciona uma nova linha a cada chamada de impressão, o -n significa "leia a entrada linha por linha" e o -e permite que você passe um script na linha de comando. O script em si corresponde a sda3 e, em seguida, qualquer trecho de caracteres até espaço em branco seguido por um ou mais números ( \s(\d+) ), espaço em branco seguido por um intervalo de números que terminam com % ( \s+\d+ ). Os parênteses capturam a parte em que estamos interessados, que é então impressa como $1 .

Ou

df | tr -s ' ' $'\t' | grep sda3 | cut -f4

Explicação

Aqui, simplesmente usamos tr para converter vários espaços consecutivos em uma guia (o delimitador padrão de cut ), depois grep para sda3 e imprime o quarto campo.

    
por 25.09.2014 / 12:57
5

Como usar grep para resolvê-lo como você pergunta já está respondido;
Esta resposta é sobre como resolver o exemplo problema - obtendo um valor separado de df :

O GNU df de coreutils tem uma opção para especificar as colunas mostradas na saída:

$ df --output=avail /dev/sda3
  Avail
9816416

Infelizmente, não há opção para suprimir o cabeçalho da coluna - por isso, ele precisa ser descartado em uma etapa extra, com tail :

$ df --output=avail /dev/sda3 | tail -n 1
9816416

ou grep , se você preferir:

$ df --output=avail /dev/sda3 | grep '[0-9]'
9816416
    
por 25.09.2014 / 16:40
2

Dependendo da sua versão do grep, você também pode usar -o apenas e -E para regex estendida.

Então você pode usar

df | grep /dev/sda3 | grep -E -o "[[:digit:]]+[[:space:]]+[[:digit:]]+%" | grep -E -o ".+\s"

Isso precisa do % char como uma âncora para o primeiro grep. Depois disso, você recebe os primeiros caracteres até o espaço com o segundo grep.

    
por 25.09.2014 / 12:41