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}' "