Extrair palavra da string usando grep / sed / awk

12

Eu tenho uma corda

00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256

e deseja extrair a palavra qaa seguir -Dspring.profiles.active.

Eu tenho a seqüência de salvar em um arquivo text.txt apenas para demonstração nele.

Quando eu faço

grep -r -o "spring.profiles.active=" text.txt

O resultado é spring.profiles.active=

Esta palavra nem sempre é qa, poderia ser prodou dev.

O que eu gostaria de fazer é encontrar a palavra spring.profiles.activee após o =extrato essa palavra.

Gostaria de fazer o shell script disso porque uso a palavra para configurar outros itens no servidor.

Isso é possível e, em caso afirmativo, como faço.

Gman
fonte
Suponho que já existam meta conversas sobre isso, mas essa pergunta é completamente inespecífica para o Ubuntu. Por que está aqui em vez de unix.stackexchange.com ?
Tony Adams
@TonyAdams Sim, existem: perguntas sobre processamento de texto foram abordadas indiretamente aqui e, de fato, sempre foram consideradas no tópico e nunca foram fechadas / migradas; na especificidade do Ubuntu, que foi abordada várias vezes, duas vezes recentemente aqui e na duplicata e outra aqui .
kos
boa pergunta! : D
ncomputers

Respostas:

18

Você pode usar grepcom PCRE ( -P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active=corresponderá a essa substring literalmente, \Kdescartará a correspondência

  • [^ ]+selecionará a porção desejada, ou seja, a porção seguinte spring.profiles.active=, até o próximo espaço

Para um arquivo:

grep -Po 'spring.profiles.active=\K[^ ]+' file.txt

Exemplo:

% grep -Po 'spring.profiles.active=\K[^ ]+' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
qa

sed levaria lógica semelhante:

sed -r 's/.*spring.profiles.active=([^ ]+).*/\1/' <<<'.....string.....'

Exemplo:

% sed -r 's/.*spring.profiles.active=([^ ]+).*/\1/' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
qa

Manipulando erros:

No seu script, você pode lidar com o caso em que não há correspondência, ou seja, onde a string original não contém spring.profiles.active=. No sedexemplo acima , você obtém toda a cadeia original, o que pode criar problemas:

% var="$(sed -r 's/.*spring.profiles.active=([^ ]+).*/\1/' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -XX:MaxPermSize=256')"
% echo $var
00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -XX:MaxPermSize=256

Se você preferir obter a sequência vazia quando não houver correspondência, adicione a -nopção ao sedcomando e a popção ao sed scomando, desta forma:

% var="$(sed -rn 's/.*spring.profiles.active=([^ ]+).*/\1/p' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -XX:MaxPermSize=256')"
% echo $var

% var="$(sed -rn 's/.*spring.profiles.active=([^ ]+).*/\1/p' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256')"
% echo $var
qa

Então você pode testar se $ var está vazio ou não.

heemail
fonte
Obrigado @heemay, funciona perfeito. agora eu só preciso escrever isso. Vou marcá-lo como respondeu
Gman
@ heemay você saberia como eu poderia escrever isso. Eu tenho isso em um script e quando ele roda ele retorna qa. Quero salvar o resultado em uma variável chamada env e depois compará-la com algo parecido. Se [env == qa]; então // fazer alguma coisa ... else fazer alguma coisa ...
Gman
1
@Gman Sim .. é só usar substituição de comando: var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"substituir file.txtcom <<<'...string...'se a entrada é uma string, não um file..then você pode fazerif [ "$var" = 'qa' ]; then do something; else do something; fi
heemayl
1

Usando awk

awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' <<<'your_string'

ou

awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' your_file

Exemplo

% awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
qa
AB
fonte
1

Vou jogar um Perl na mistura:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: ativa o processamento automático de final de linha. Tem dois efeitos separados. Primeiro, ele copia automaticamente $ / (o separador de registro de entrada) quando usado com -n ou -p. Segundo, ele atribui $ \ (o separador de registro de saída) para ter o valor de octnum, para que quaisquer instruções de impressão tenham esse separador adicionado novamente. Se o octnum for omitido, configure $ \ para o valor atual de $ /.
  • -a: ativa o modo de divisão automática quando usado com -n ou -p. Um comando de divisão implícito na matriz @F é feito como a primeira coisa dentro do loop while implícito produzido pelo -n ou -p.
  • n: faz com que o Perl assuma o seguinte loop em torno do seu programa, o que faz com que ele itere sobre os argumentos do nome do arquivo, como sed -n ou awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: pode ser usado para inserir uma linha do programa.
% <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
qa
kos
fonte
regex original também pode ser usado assim:perl -nle '/spring.profiles.active=\K([^ ]+)/ && print $1' <<<'00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256'
Manwe 12/11