Retorna um valor e salva em uma variável

0

Eu tenho esta frase que retorna dois valores.

cat /ora$sid/dbs/listener.ora|grep PORT|sed 's/.*PORT.*\([0-9]\{4\}\)\(.*\)//'

Return
1521
1522

Com esta frase, quero obter apenas um valor. Este valor eu quero salvá-lo em uma variável para construir uma string sqlplus para conectar-se automaticamente ao banco de dados oracle e, em seguida, executar um comando.

Como posso limitar o número de resultados retornados e salvá-lo em uma variável? Para usar este valor posteriormente em outro comando?

Atualização:

Eu adicionei a sentença em uma chamada ssh mas quando eu a executo eu não recebo nenhum valor (sem chamada ssh funcionar bem com head -1)

read -p "Maquina : " maquina; read -p "SID : " sid; ssh ora$sid@'echo $maquina' "port=$(cat /ora$sid/dbs/listener.ora|grep PORT|sed 's/.*PORT.*\([0-9]\{4\}\)\(.*\)// ' | head -1)| echo $port"
    
por estonolose 24.06.2016 / 13:40

5 respostas

1

Dada a maneira como você construiu o comando, por recomendação seria usar head , tail ou alguma combinação dos dois para obter apenas um resultado. Se você quer apenas o primeiro resultado, head -1 deve fazê-lo. Se você estiver procurando por um número de linha específico, provavelmente será necessário uma combinação de head e tail .

    
por 24.06.2016 / 13:43
1

Se você quiser o primeiro valor retornado, use |head -1 para obtê-lo.

Você pode usar a estrutura $() para retorná-la como um valor eg

port=$(cat /ora$sid/dbs/listener.ora|grep PORT|sed 's/.*PORT.*\([0-9]\{4\}\)\(.*\)//' | head -1)
    
por 24.06.2016 / 13:44
1

Isso é um monte de comandos fazendo as mesmas coisas que apenas um comando pode fazer.

Eu não sei como "listener.ora" está formatado, mas a linha abaixo deve funcionar bem, no máximo com alguns pequenos ajustes.

sed -rn '/PORT/ s/.*([0-9]{4}).*//p' /ora$sid/dbs/listener.ora

-r para regex
-n para suprimir a impressão automática
/PORT/ para localizar a linha contendo PORT% s/ para substituir /p para imprimir as linhas editadas

Use a cabeça ou a cauda para obter um ou os outros valores.

$PORT0=(sed -rn '/PORT/ s/.*([0-9]{4}).*//p' /ora$sid/dbs/listener.ora | head -1)

Ou se você quiser os dois:

grab_port () { sed -rn '/PORT/ s/.*([0-9]{4}).*//p' /ora$sid/dbs/listener.ora ; }
$PORT0=$(grab_port|head -1)
$PORT1=$(grab_port|tail -1)

Agora, vamos ver sua linha:

read -p "Maquina : " maquina; read -p "SID : " sid; ssh ora$sid@'echo $maquina' "port=$(cat /ora$sid/dbs/listener.ora|grep PORT|sed 's/.*PORT.*\([0-9]\{4\}\)\(.*\)// ' | head -1)| echo $port"

A parte que começa com "port= termina com | echo $port" , canalizando o resultado de sua própria variável para si mesmo ... não o que você deseja fazer aqui. Edit: Sem contar que nem está rodando o comando ou fazendo a variável. Apenas não é construído corretamente.

Se você definir a variável port antes, ficará mais fácil também.

read -p "Maquina : " maquina; read -p "SID : " sid; ssh ora$sid@'echo $maquina' "$PORT0"
    
por 24.06.2016 / 17:06
1

Para a pergunta geral em seu título, head -1 ou sed -n 1p - ou sed 1q - são maneiras de selecionar a primeira linha de qualquer coisa.

Mas seu caso é selecionar o primeiro resultado de substituição por sed . Você pode obter isso de sed com uma pequena modificação, e também pode fazer o equivalente de seu grep e seu inútil cat , além de precisar apenas de um de seus grupos de captura:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*//p;q}' 
# -n don't output input lines by default
# /PORT/ when an input line contains the string PORT
#    {s/...//p; extract only the 4digits after PORT and print them
#    q} and then terminate sed processing, so we onloy get one value

ADICIONADO: você também pode evitar a contrabarra no regexp se usar -r , como o Kaffe respondeu (enquanto eu estava fazendo o rascunho), na maioria das versões de sed .

Seu caso ssh tem DOIS (ou três) problemas. Você faz:

ssh user@machine "port=$( commands ) | echo port"

Primeiro, os $( commands ) estão dentro de uma string de aspas duplas, então eles são executados na SUA máquina, não na outra máquina. Você está se conectando a $maquina , mas tentando (veja a seguir) dizer a ele para imprimir o número da porta para a sua máquina, o que é um desperdício de tempo. (E não é fácil corrigir isso, porque você deseja substituir $sid mais use singlequotes para o comando sed ).

Em segundo lugar, você faz port=value | echo $port . Esse pipeline executa sub-pacotes separados (na outra máquina); no primeiro subshell, define a variável port para o número da porta (da sua máquina), mas essa variável nunca é usada para nada; no segundo subshell, ele imprime o valor da porta variável, que não está definida naquela sub-camada, então você obtém uma linha vazia. Para colocar um valor em uma variável e, em seguida, usar a variável, use ; ou se você quiser ou puder depender do status de saída && ou || .

Mas você não precisa de nenhuma variável. Exceto para dividir espaços em branco e expandir globs se presentes, o que eles não estão aqui, var=$(commands); echo $var é exatamente o mesmo como commands . Da mesma forma, !echo $maquina! onde o! na verdade são backticks (não consigo encontrar uma maneira de remarcação no texto) sem whitespace ou glob (que não ocorrerá em um nome de máquina) é exatamente o mesmo que $maquina .

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*//p;q}' "
    
por 24.06.2016 / 18:44
0
grep -m1 PORT /ora$sid/dbs/listener.ora | sed 's/.*PORT.*\([0-9]\{4\}\)\(.*\)//'

ou

Altere o if ($ count > NUM) para restringir o número de correspondências retornadas, aqui são 3 correspondências.

perl -e 'my $count = 0; while(<>) { if(/PORT (\d+)/) {print "$1\n"; $count+=1; if($count > 2) {exit}} }' /ora$sid/dbs/listener.ora
    
por 24.06.2016 / 16:37