Grep 3 letras maiúsculas e dígitos em duas variáveis ​​

Grep 3 letras maiúsculas e dígitos em duas variáveis ​​

Eu criei um script que usa um for looploop através de um script IBM para obter o tamanho dos diretórios. O script então exibe o tamanho do diretório e o caminho para um canal do Slack para facilitar a visualização. O programa funciona, mas a saída do script IBM é grande e precisa de formatação para facilitar a leitura no Slack. Portanto, preciso coletar duas informações que serão canalizadas para duas variáveis ​​separadas, sendo as variáveis ​​usadas para criar a mensagem do Slack. Meu script se parece com:

SIZE () {
  for dir in /path/to/dir/*
  do
    cd /usr/lpp/mmfs/samples/ilm/
    SLACKMESSAGE=$(./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h)
    SLACK
  done
}

O mesmo /path/to/dir/*ocorre com o diretório pai e o script IBM ./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h percorrerá todos os diretórios filhos (um nível de profundidade) e obterá seu tamanho. A saída é semelhante a:

[I] 2018-05-31@16:32:55.798 Policy execution. 0 files dispatched.
[I] 2018-05-31@16:32:55.804 Policy execution. 0 files dispatched.
File system scan complete.
534.5M     total
mmapplypolicy du for /path/to/directory/SPI/ complete at Thu May 31 17:32:55 2018

Essa não é a saída mais limpa, então eu gostaria de canalizar o tamanho do diretório no caso do exemplo acima 534.5Mpara uma variável chamada SIZEe SPIpara outra variável chamada PROJECT. É claro que sendo um loop, a SIZEvariável PROJECTand mudará em cada diretório dentro do exemplo acima /path/to/dir/. A função Slack que é chamada na função acima usará essas duas variáveis. Estou lutando para descobrir como colocar esses dois em variáveis. Alguém tem uma solução? Obrigado!

Responder1

Para fazer isso de uma só vez:

eval "$(yourscript | awk -v q=\' '
  $1 ~ /^[[:digit:]]+(\.[[:digit:]]+)?[MGT]$/ {
    print "SIZE=" $1
  }
  match($0, /[[:upper:]]{3}/) {
    print "PROJECT="q substr($0, RSTART, RLENGTH) q
  }')"

Observe que algumas awkimplementações como o nawkSolaris mawkou versões mais antigas do gawknão suportam os operadores de intervalo de expressão regular {x,y}/ {x}(no caso de versões mais antigas (e não antigas) do gawk, você pode executá-lo POSIXLY_CORRECT=anythingno ambiente para suportá-los embora) embora seja padrão há mais de 25 anos. Com eles, você precisaria substituir [[:upper:]]{3}por [[:upper:]][[:upper:]][[:upper:]].

Responder2

Duvido muito que seja disso que você precisa, mas isso responde literalmente à sua pergunta atual.

Primeira parte (assumindo GNU grepou compatível):

project="$(yourscript|grep -oE '[[:upper:]]{3}')"

Segunda parte:

size="$(yourscript|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"

Combinados, é mais simples executar o script uma vez, salvar a saída e grep e atribuir na saída salva:

output="$(script)"
size="$(printf '%s\n' "$output"|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"
project="$(printf '%s\n' "$output"|grep -oE '[[:upper:]]{3}')"

Alguma explicação
grep -o- retorne apenas o objeto grepado, não a linha inteira
-E- Regex estendido
[[:upper:]]- corresponda apenas a letras maiúsculas ([AZ], mas independentemente da localidade)
{3}- limite a correspondência a exatamente 3 caracteres consecutivos.
[[:digit:]]- combinar dígitos ([0-9], novamente sem considerar a localidade)
+- combinar 1 ou mais vezes
\.- combinar um ponto
(...)?- combinar 0 ou 1 vezes - isso garante que números sem um ponto decimal também possam ser capturados
[xy]- combinar exatamente um dos itens x ou y.

informação relacionada