Analisando uma string de versão do Hadoop com Bash

1

temos esta sintaxe CLI

hdp-select | grep hadoop-client
hadoop-client - 2.6.4.0-91

o objetivo final é obter o número como exemplo:

2640

nós capturamos o último número & remova o - e remova o .

então eu fiz

 hdp-select | grep hadoop-client | awk '{print $3}' | sed s'/-/ /g' | awk '{print $1}' | sed s'/\.//g'
 2640

mas esta é uma solução feia

Ficarei feliz em conhecer outra solução elegante

    
por jango 21.01.2018 / 13:56

9 respostas

5

com sed

hdp-select | sed '/^hadoop-client - /!d;s///;s/-.*//;s/\.//g'
    
por 21.01.2018 / 14:36
3

Solução otimizada com programa único awk :

hdp-select | awk -F'-' '/^hadoop-client/{ gsub(/[[:space:].]+/, "", $3); print $3; exit }'

A saída:

2640
    
por 21.01.2018 / 14:32
3

Você pode fazer isso facilmente no bash:

input='2.6.4.0-91'
input=${input%-*}
input=${input//./}
echo "$input"
2640
    
por 21.01.2018 / 14:37
1

Com awk: use - , . e espaço como separadores e imprima as colunas 5 a 8.

hdp-select | awk -F '[-. ]' '/hadoop-client/ {print $5$6$7$8}'

Saída:

2640
    
por 21.01.2018 / 15:38
1

Outro sed , sem dúvida mais simples que o outro (dois comandos vs três):

hdp-select | sed -n 's/hadoop-client - \(.*\)-.*//;s/\.//gp'
    
por 21.01.2018 / 16:35
0

Você pode usar a ferramenta de coluna do pacote util-linux:

column -t -s . -o '' <<'eof'
1.0.0
eof

Ou:

echo 1.0.0 | column -t -s . -o ''

Resultado:

100
    
por 21.01.2018 / 20:03
0

Veja como eu faria:

input="hadoop-client - 2.6.4.0-91"
if [[ "$input" =~ ([0-9\.]+) ]] ; then
    value=${BASH_REMATCH[1]} 
    value=${value//./}
    echo "Matched '$value'"
else
    echo "Unparseable"
fi

Não é uma linha, mas isso é uma vantagem para mim. É legível e usa apenas as ferramentas necessárias - uma expressão regular para extrair os dígitos do número da versão e, em seguida, um substituto para retirar o '.' personagens. Além disso, ele dá uma forma básica de validação de que o que foi dado é o esperado - se você quisesse ser mais cauteloso, lançaria hadoop-client\ -\ antes do colchete na regex para verificar se a entrada é realmente o que você pensa deveria ser.

Depende de expressões regulares no bash, mas como elas existem desde a versão 3 do bash (2004), provavelmente está tudo bem.

    
por 21.01.2018 / 23:12
0

É possível fazer isso diretamente no shell (bash):

$ re='hadoop-client - ([0-9]+).([0-9]+).([0-9]+).([0-9]+)-'
$ a=$(hdp-select)
$ (IFS='' ; [[ $a =~ $re ]] && echo "${BASH_REMATCH[*]:1}" )
2640

Se você estiver limitado a shells mais antigos, use uma regex similar com expr :

$ expr "$(hdp-select)" : '.*client - \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)-.*' | sed 's/\.//g'
    
por 04.07.2018 / 14:45
0

Esta solução é adequada para alguém que conhece expressões regulares e não sabe sed ou awk .

expr e tr vêm de "GNU Core Utilities". Infelizmente, expr usa expressão regular básica e cada expressão regular é ancorada com ^ .

expr "$(hdp-select)" : '.*oop-client - \(\([0-9]\+\.\?\)\+\)-[0-9]\+' | tr -d '.'

Resultado:

2640
    
por 04.07.2018 / 11:24