Como posso analisar uma saída de comando de várias linhas no bash?

0

Eu tenho um comando que gera o seguinte:

Some text here
    1,3456: "Descr 1"
    2,7891: "Descr 2"
    3,0976: "Descr 3"

Some other random text here

Eu quero escrever um script bash que analise a primeira coluna e armazene os valores em algum lugar, para que eu possa apresentar as opções para um usuário final.

Eu posso usar o awk para obter a primeira coluna, mas por causa desse texto aleatório no final ("Algum outro texto aleatório aqui"), está atrapalhando o meu comando do awk.

Isso é o que eu tenho até agora:

#!/bin/bash

VERSIONS='/usr/libexec/somebin -V'

OPTIONS=$VERSIONS | awk -F'[,]' '{print $1}'

while read -r line; do
   echo "... $line ..."
done <<< $OPTIONS

e tudo o que faz é imprimir:

Some text here
    1,3456: "Descr 1"
    2,7891: "Descr 2"
    3,0976: "Descr 3"

...  ...

Mas eu queria que fosse impresso:

1
2
3
    
por jcm 03.02.2016 / 00:43

3 respostas

2

O comando simples antes do pipe em:

OPTIONS=$VERSIONS | awk -F'[,]' '{print $1}'

define OPTIONS para $VERSIONS . Como não há nenhum nome de utilitário real, o comando é simplesmente uma atribuição e, portanto, não produz saída. Portanto, nada é canalizado para awk e, consequentemente, awk não faz nada. (E mesmo se fizesse alguma coisa, não faria isso para $OPTIONS .

Ainda pior, o pipe garante que tanto o comando antes quanto o comando após sejam executados em subshells. Portanto, OPTIONS não está definido no shell que contém o comando composto.

Eu presumo que o que você queria era algo assim:

OPTIONS=$(/usr/libexec/somebin -V | cut -f1 -d,)

ou talvez

VERSIONS=$(/usr/libexec/somebin -V)
OPTIONS=$(echo "$VERSIONS" | cut -f1 -d,)

em que o comando cut faz exatamente a mesma coisa que sua invocação de awk .

Mas nem isso nem seu comando awk filtrarão as linhas com "algum texto", então talvez você precise de um filtro real, talvez algo assim:

VERSIONS=$(/usr/libexec/somebin -V | grep ,)
OPTIONS=$(echo "$VERSIONS" | cut -f1 -d,)
    
por 03.02.2016 / 03:48
1
awk -F'[,]' '/^[ ]/{print $1}'

Atuaria somente em linhas que começam com um espaço, pulando as que não possuem. Outra opção pode ser procurar por linhas que contenham uma vírgula, ou um regex diferente, se forem usadas abas insidiosas em vez de espaços ...

    
por 03.02.2016 / 01:04
0

você pode fazer isso apenas com o bash -

IFS=","; while read -r a b; do [[ $a =~ [0-9]+ ]] && echo $a; done < 1; unset IFS
1
2
3
    
por 03.02.2016 / 05:11