Extraire le mot de la chaîne en utilisant grep / sed / awk


12

J'ai une chaîne

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

et je veux extraire le mot qaqui suit -Dspring.profiles.active.

J'ai la chaîne de sauvegarde dans un fichier text.txt juste pour faire une démonstration dessus.

Quand je fais

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

Le résultat est spring.profiles.active=

Ce mot n'est pas toujours qa, il pourrait être prodou dev.

Ce que je voudrais faire, c'est trouver le mot spring.profiles.activeet après l' =extraire ce mot.

Je voudrais décortiquer ce script car j'utilise le mot pour configurer d'autres éléments sur le serveur.

Est-ce possible et si oui, comment le faire.


Je suppose qu'il y a déjà eu des méta-conversations à ce sujet, mais cette question n'est absolument pas spécifique à Ubuntu. Pourquoi est-il ici au lieu d' unix.stackexchange.com ?
Tony Adams,

@TonyAdams Oui, il y en a: les questions de traitement de texte ont été indirectement couvertes ici , et de toute façon, de facto, elles ont toujours été considérées sur le sujet et jamais fermées / migrées; sur la spécificité d'Ubuntu, qui a été abordée plusieurs fois, deux fois récemment ici et en double et une fois ici .
kos

bonne question! : D
ncomputers

Réponses:


19

Vous pouvez utiliser grepavec PCRE ( -P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active=correspondra littéralement à cette sous-chaîne, \Ksupprimera la correspondance

  • [^ ]+sélectionnera la portion souhaitée, c'est-à-dire la portion suivante spring.profiles.active=, jusqu'à l'espace suivant

Pour un fichier:

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

Exemple:

% 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 prendrait une logique similaire:

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

Exemple:

% 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

Gestion des erreurs:

Dans votre script, vous voudrez peut-être gérer le cas où il n'y a pas de correspondance, en d'autres termes où votre chaîne d'origine ne contient pas spring.profiles.active=. Dans l' sedexemple ci-dessus , vous obtenez toute la chaîne d'origine, ce qui pourrait créer des problèmes:

% 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 vous préférez obtenir la chaîne vide lorsqu'il n'y a aucune correspondance, ajoutez l' -noption à la sedcommande et l' poption à la sed scommande, comme ceci:

% 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

Ensuite, vous pouvez tester si $ var est vide ou non.


Merci @heemay, fonctionne parfaitement. maintenant j'ai juste besoin de faire ça. Je le marquerai comme répondu
Gman

@heemay sauriez-vous comment je pourrais écrire ceci. Je l'ai dans un script et quand il s'exécute, retournez qa. Je veux enregistrer le résultat dans une variable appelée env, puis comparer cela à quelque chose comme. If [env == qa]; puis // FAIRE quelque chose ... sinon faire quelque chose ...
Gman

1
@Gman Ouais .. utilisez simplement la substitution de commande: var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"remplacez file.txtpar <<<'...string...'si l'entrée est une chaîne, pas un fichier .. alors vous pouvez le faireif [ "$var" = 'qa' ]; then do something; else do something; fi
heemayl

1

En utilisant awk

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

ou

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

Exemple

% 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

Je vais jeter un Perl dans le mélange:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: active le traitement automatique de fin de ligne. Il a deux effets distincts. Tout d'abord, il compile automatiquement $ / (le séparateur d'enregistrement d'entrée) lorsqu'il est utilisé avec -n ou -p. Deuxièmement, il affecte $ \ (le séparateur d'enregistrements de sortie) pour avoir la valeur d'octnum afin que toutes les instructions d'impression aient ce séparateur ajouté à nouveau. Si octnum est omis, définit $ \ à la valeur actuelle de $ /.
  • -a: active le mode autosplit lorsqu'il est utilisé avec -n ou -p. Une commande de division implicite du tableau @F est effectuée comme première chose à l'intérieur de la boucle while implicite produite par -n ou -p.
  • n: oblige Perl à assumer la boucle suivante autour de votre programme, ce qui le fait parcourir les arguments de nom de fichier un peu comme sed -n ou awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: peut être utilisé pour entrer une ligne de programme.
% <<<'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

regex original peut être utilisé aussi comme ceci: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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.