Localizando números em uma saída de comando e salvando-a como variáveis

3

Em um script bash, desejo obter alguns números da saída de um comando e armazená-los em variáveis. Um exemplo da saída do comando:

25 results [22 valid, 2 invalid, 1 undefined]

Eu gostaria de salvar os quatro números na saída de comando anterior como variáveis chamadas results, valid, invalid, undefined .

    
por nabeelj 12.09.2018 / 16:57

5 respostas

3

Digamos que a saída desse comando seja salva em um arquivo chamado output.txt e, em seguida, você pode usar os comandos awk e grep da seguinte maneira:

results=$(grep results output.txt | awk '{print $1}')    
valid=$(grep valid output.txt | awk '{print $3}' | tr -d [])
invalid=$(grep invalid output.txt | awk '{print $5}' | tr -d [])
undefined=$(grep undefinedoutput.txt | awk '{print $7}' | tr -d [])

Inclua estas quatro linhas na sua festa onde elas se encaixam.

Em vez disso, você só pode usar awk para encontrar um padrão correspondente, da seguinte maneira:

results=$(awk '/results/{ print $1 }' output.txt)
valid=(awk '/valid/{ print $3 }' output.txt | tr -d [])
invalid=(awk '/invalid/{ print $5 }' output.txt | tr -d [])
undefined=(awk '/undefined/{ print $7 }' output.txt | tr -d [])
    
por 12.09.2018 / 17:06
6

Como você deseja armazenar vários valores separados, presumo que você queira armazená-los em uma matriz:

$ str='25 results [22 valid, 2 invalid, 1 undefined]'

$ readarray -t arr < <( grep -E -o '[0-9]+' <<<"$str" )

Isso lê a saída de grep em uma matriz chamada arr . O comando grep exibirá cada número separado encontrado em $str em sua própria linha, combinando a expressão regular estendida [0-9]+ com a string e extraindo cada correspondência. grep lê a string de "here-string" e readarray lê o resultado de grep usando uma substituição de processo.

Os valores podem então ser usados como

$ printf 'value: %s\n' "${arr[@]}"
value: 25
value: 22
value: 2
value: 1

ou, para ver valores individuais, use, e. "${arr[0]}" , "${arr[1]}" , etc. O array contém "${#arr}" valores.

results=${arr[0]}
valid=${arr[1]}
invalid=${arr[2]}
undefined=${arr[3]}

Para ler diretamente de um comando:

readarray -t arr < <( mycommand | grep -E -o '[0-9]+' )
    
por 12.09.2018 / 17:23
3

Supondo que sua saída esteja em uma variável chamada output, você pode dividi-la com sed, mantendo apenas os espaços e dígitos, para permitir que você divida facilmente as "palavras" em uma matriz:

tim@host:~$ res=($(sed 's/[^0-9 ]*//g' <<< $output))
tim@host:~$ printf "results: %s\nvalid: %s\ninvalid: %s\nundefined: %s\n" "${res[@]}"
results: 25
valid: 22
invalid: 2
undefined: 1
    
por 12.09.2018 / 17:36
2

Você pode usar a expansão de parâmetro para substituir tudo o que não é um dígito por um espaço e usar a divisão de palavras para ler o resultado em suas variáveis:

str='25 results [22 valid, 2 invalid, 1 undefined]'
read results valid invalid undefined <<< ${str//[![:digit:]]/ }

A expansão resulta em algo como

$ echo "${str//[![:digit:]]/ }"
25          22        2          1

e read fazem o resto.

    
por 12.09.2018 / 23:20
0

Em qualquer shell POSIX:

a='aja 25 results [22 valid, 2 invalid, 1 undefined]'

set --                         # clean the list of argumnets.
while [ ${#a} -gt 0 ]; do      # while a is not empty, loop.
    b=${a%%[0-9]*}             # extract leading characters that are not digits (if any).
    a=${a#"$b"}                # remove those from the source variable.
    b=${a%%[^0-9]*}            # extract the leading digits.
    set -- "$@" ${a:+"$b"}     # until a empty, add numbers to the list.
    a=${a#"$b"}                # remove the digits from the source string.
done

printf '<%s> ' "$@"; echo      # print the list of values.
    
por 23.09.2018 / 06:44

Tags