Estou tentando obter texto entre caracteres especiais. Você pode seguir o abaixo para entender o que estou tentando obter. Tenho os comandos necessários para fazer isso, no entanto, estou procurando uma maneira mais eficiente, caso certas condições possam mudar com base no resultado.
Abaixo tem o texto On-Line (Prim) por exemplo. Quero extrair qualquer texto entre "--" 1ª e 2ª ocorrência.
Então eu tenho o texto abaixo na variável "VAL1"
IBM Informix Dynamic Server Version 14.10.FC10XA -- On-Line (Prim) -- Up 77 days 23:08:31 -- 130337920 Kbytes
Então atualmente estou usando o seguinte:
echo "$VAL1" | awk -F'--' '$1 ~ /Version/ {print $2}'
O acima fornece a saída abaixo:
On-Line (Prim)
No entanto, você não consegue ver que há necessariamente um espaço em branco no final da linha, mas o início é bem perceptível. Quero garantir que eu imprima apenas as palavras entre "--" que excluam quaisquer espaços em branco antes e depois da frase dentro de "--".
Então tentei usar o seguinte, que para mim parece estar bom:
echo "$VAL1" | awk -F'--' '$1 ~ /Version/ {print $2}' | sed 's/^ //g' | sed 's/ *$//'
Saída:
On-Line (Prim)
Gostaria de saber se existe uma maneira melhor e mais fácil de fazer isso que seja mais suficiente?
Basta estender seu separador de campo de
--
para--
...Ou para imprimi-lo somente se houver pelo menos 2 ocorrências de
--
na linha:Ou outra alternativa - usando awk's
gsub
:Como você está no AIX, você deve ter acesso ao shell ksh93 que suporta (uma forma limitada de) expressões regulares perl onde você pode fazer:
Ou o mesmo com zsh (onde expressões regulares perl são suportadas pela biblioteca PCRE, portanto com suporte mais completo do que no ksh93):
(não usar
$status
aqui, pois essa é a variável especial que contém o status de saída do último comando, como na maioria dos outros shells (exceto aqueles do tipo Bourne, onde é$?
(que o zsh também suporta como um alias)).Com
awk
:Lá, estamos passando o valor de
$VAL1
como argumento para,awk
em vez de, em seu stdin, o que tem alguns benefícios:echo
não pode ser usado para dados arbitrários, pois dependendo da implementação e/ou do ambiente de compilação/execução, ele processa algumas opções e/ou destrói barras invertidas (usarprintf '%s\n' "$VAL1"
ouprint -r -- "$VAL1"
em ksh/zsh ou usar um heredoc ou herestring não teria esse problema).No entanto, observe que como
awk
é um comando externo, isso significa que o valor é visível para qualquer pessoa no sistema (como na saída deps
if executado no momento certo) e você pode atingir oexecve()
limite no tamanho dos argumentos+environ (por padrão, relativamente grande (1 MiB) no AIX 7.{1..3}).Passar o valor pelo ambiente evitaria o primeiro problema:
Assim como
FS
(conforme definido por-F
), o argumento separador desplit()
é uma expressão regular, então podemos incluir[[:space:]]*
(qualquer quantidade de espaço em branco) ao redor--
dele.Supondo que o OP queira capturar o resultado em outra variável, podemos realizar um par de substituições de parâmetros em vez de invocar alguns subshells para chamar
awk
oused
, por exemplo:As páginas de informações do GNU awk listam uma biblioteca de funções adicional que pode ter uma função trim...
Este site tem uma função ok trim que você pode adicionar à 'biblioteca de funções do sistema GAWK' (acho que é um cfg em ~/.gawkrc ou algo assim) --
https://gist.github.com/andrewrcollins/1592991
Trim é uma função útil para adicionar à biblioteca. As páginas de informação têm essa 'biblioteca de funções' no diretório inicial, mas não está nas páginas man, etc.