Wyodrębnij słowo z ciągu za pomocą grep / sed / awk

12

Mam sznurek

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

i chcą, aby wyodrębnić słowa qa, który następuje -Dspring.profiles.active.

Mam zapis łańcucha w pliku text.txt, aby go tylko wypróbować.

Kiedy robię

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

Wynik to spring.profiles.active=

To słowo nie zawsze jest qa, może być prodlub dev.

Co chciałbym zrobić, to znaleźć wyraz spring.profiles.activei po tym =ekstrakcie tego słowa.

Chciałbym to zrobić za pomocą skryptu, ponieważ używam tego słowa do konfigurowania innych elementów na serwerze.

Czy to możliwe, a jeśli tak, to jak to zrobić.

Gman
źródło
Wydaje mi się, że były już na ten temat meta-rozmowy, ale to pytanie jest całkowicie niespecyficzne dla Ubuntu. Dlaczego jest tutaj zamiast unix.stackexchange.com ?
Tony Adams,
@TonyAdams Tak, istnieją: pytania dotyczące przetwarzania tekstu zostały tutaj pośrednio omówione , a zresztą de facto zawsze były one rozważane na temat i nigdy nie były zamykane / migrowane; na temat specyficzności Ubuntu, która była omawiana wiele razy, ostatnio dwa razy tutaj, w duplikacie i raz tutaj .
Kos
dobre pytanie! : D
nkomputery

Odpowiedzi:

20

Możesz używać grepz PCRE ( -P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active=dopasuje ten podciąg dosłownie, \Kodrzuci dopasowanie

  • [^ ]+wybierze żądaną część, tj. część po spring.profiles.active=, aż do następnej spacji

Dla pliku:

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

Przykład:

% 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 przyjąłby podobną logikę:

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

Przykład:

% 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

Błędy obsługi:

W skrypcie możesz poradzić sobie z przypadkiem, w którym nie ma zgodności, innymi słowy, gdy oryginalny ciąg nie zawiera spring.profiles.active=. W powyższym sedprzykładzie otrzymujesz cały oryginalny ciąg, co może powodować problemy:

% 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

Jeśli wolisz uzyskać pusty ciąg, gdy nie ma zgodności, dodaj -nopcję do sedpolecenia i popcję do sed spolecenia, w następujący sposób:

% 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

Następnie możesz sprawdzić, czy $ var jest puste, czy nie.

heemayl
źródło
Dzięki @heemay, działa idealnie. teraz muszę to napisać.
Oznaczę
@ heemay czy wiesz, jak mogłem to napisać. Mam go w skrypcie i po uruchomieniu zwraca qa. Chcę zapisać wynik w zmiennej o nazwie env, a następnie porównać to z czymś takim. Jeśli [env == qa]; następnie // Zrób coś ... jeszcze Zrób coś ...
Gman,
1
@Gman Taa .. po prostu użyć podstawienia polecenia: var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"wymienić file.txtze <<<'...string...'jeśli wejście jest ciągiem znaków, a nie file..then można zrobićif [ "$var" = 'qa' ]; then do something; else do something; fi
heemayl
1

Za pomocą awk

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

lub

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

Przykład

% 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
źródło
1

Wrzucę Perla do miksu:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: umożliwia automatyczne przetwarzanie końca linii. Ma dwa osobne efekty. Po pierwsze, automatycznie używa komendy $ / (separator rekordów wejściowych), gdy jest używana z -n lub -p. Po drugie, przypisuje $ \ (separator rekordu wyjściowego), aby miał wartość octnum, dzięki czemu wszelkie instrukcje drukowania będą miały ponownie dodany separator. Jeśli octnum zostanie pominięty, ustawia $ \ na bieżącą wartość $ /.
  • -a: włącza tryb automatycznego podziału, gdy jest używany z -n lub -p. Ujawnione polecenie podziału na tablicę @F jest wykonywane jako pierwsza rzecz w niejawnej pętli while generowanej przez -n lub -p.
  • n: powoduje, że Perl zakłada następującą pętlę wokół twojego programu, co powoduje iterację argumentów nazw plików, takich jak sed -n lub awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: może być użyty do wprowadzenia jednego wiersza programu.
% <<<'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
źródło
wyrażenie regularne może być również użyte w następujący sposób: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,