Extraiga la palabra de la cadena usando grep / sed / awk

12

Tengo una cuerda

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

y quiero extraer la palabra qaque sigue -Dspring.profiles.active.

Tengo la cadena guardada en un archivo text.txt solo para hacer una demostración en ella.

Cuando lo hago

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

El resultado es spring.profiles.active=

Esta palabra no siempre es qa, podría ser prodo dev.

Lo que me gustaría hacer es encontrar la palabra spring.profiles.activey después el =extracto de esa palabra.

Me gustaría hacer un script de shell porque uso la palabra para configurar otros elementos en el servidor.

¿Es esto posible? Y si es así, ¿cómo lo hago?

Gman
fuente
Supongo que ya ha habido conversaciones meta sobre esto, pero esta pregunta es completamente no específica para Ubuntu. ¿Por qué está aquí en lugar de unix.stackexchange.com ?
Tony Adams
@TonyAdams Sí, sí: las preguntas de procesamiento de texto se han cubierto indirectamente aquí , y de hecho, siempre se han considerado sobre el tema y nunca se han cerrado / migrado; sobre la especificidad de Ubuntu, que se ha cubierto varias veces, dos veces recientemente aquí y en el duplicado y una vez aquí .
kos
¡buena pregunta! : D
ncomputers

Respuestas:

19

Puede usar grepcon PCRE ( -P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active=coincidirá con esta subcadena literalmente, \Kdescartará la coincidencia

  • [^ ]+seleccionará la porción deseada, es decir, la porción posterior spring.profiles.active=, hasta el siguiente espacio

Para un archivo:

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

Ejemplo:

% 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 tomaría una lógica similar:

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

Ejemplo:

% 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

Errores de manejo:

En su secuencia de comandos, es posible que desee manejar el caso donde no hay coincidencia, en otras palabras, donde su cadena original no contiene spring.profiles.active=. En el sedejemplo anterior , obtiene la cadena original completa, lo que podría crear 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

Si prefiere obtener la cadena vacía cuando no hay coincidencia, agregue la -nopción al sedcomando y la popción al sed scomando, así:

% 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

Luego puede probar si $ var está vacío o no.

heemayl
fuente
Gracias @ heemay, funciona perfecto. ahora solo necesito escribir eso. Lo marcaré como respondido
Gman
@heemay, ¿sabrías cómo podría escribir esto? Lo tengo en un script y cuando se ejecuta devuelve qa. Quiero guardar el resultado en una variable llamada env y luego compararlo con algo así. Si [env == qa]; entonces // HACER algo ... más Hacer algo ...
Gman
1
@Gman Sí .. sólo tiene que utilizar la sustitución de comandos: var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"reemplazar file.txtcon <<<'...string...'si la entrada es una cadena, no un file..then que puede hacerif [ "$var" = 'qa' ]; then do something; else do something; fi
heemayl
1

Utilizando awk

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

o

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

Ejemplo

% 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
fuente
1

Lanzaré una Perl en la mezcla:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: habilita el procesamiento automático de final de línea. Tiene dos efectos separados. Primero, automáticamente divide $ / (el separador de registro de entrada) cuando se usa con -n o -p. En segundo lugar, asigna $ \ (el separador de registro de salida) para tener el valor de octnum, de modo que cualquier declaración de impresión tendrá ese separador agregado nuevamente. Si se omite octnum, establece $ \ en el valor actual de $ /.
  • -a: activa el modo de división automática cuando se usa con -n o -p. Un comando de división implícito para la matriz @F se realiza como lo primero dentro del bucle while implícito producido por -n o -p.
  • n: hace que Perl asuma el siguiente ciclo alrededor de su programa, lo que lo hace iterar sobre argumentos de nombre de archivo algo así como sed -n o awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: puede usarse para ingresar una línea de 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
fuente
La expresión regular original también se puede usar así: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