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?


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.


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

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.