
Eu criei um script que usa um for loop
loop 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.5M
para uma variável chamada SIZE
e SPI
para outra variável chamada PROJECT
. É claro que sendo um loop, a SIZE
variável PROJECT
and 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 awk
implementações como o nawk
Solaris mawk
ou versões mais antigas do gawk
nã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=anything
no 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 grep
ou 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.