Извлечь слово из строки, используя grep / sed / awk

12

У меня есть строка

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

и хочу извлечь слово, qaкоторое следует -Dspring.profiles.active.

У меня есть строка сохранить в файл text.txt просто для демонстрации на нем.

Когда я делаю

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

Результат spring.profiles.active=

Это слово не всегда qa, может быть prodили dev.

То , что я хотел бы сделать , это найти слово spring.profiles.activeи после того, как в =экстракте этого слова.

Я хотел бы написать скрипт, потому что я использую слово для настройки других элементов на сервере.

Возможно ли это, и если да, то как мне это сделать.

Gman
источник
Я предполагаю, что уже были мета-разговоры об этом, но этот вопрос совершенно не специфичен для Ubuntu. Почему именно здесь, а не unix.stackexchange.com ?
Тони Адамс
@TonyAdams Да там есть: обработка текстов вопросы были косвенно покрыты здесь , и во всяком случае де-факто они всегда рассматриваются в теме и не закрыты / мигрировали; о специфичности для Ubuntu, которая была рассмотрена несколько раз, дважды только недавно здесь и в дубликате и один раз здесь .
Кос
хороший вопрос! : D
ncomputers

Ответы:

19

Вы можете использовать grepс PCRE ( -P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active=будет сопоставлять эту подстроку буквально, \Kбудет отбрасывать совпадение

  • [^ ]+выберет желаемую часть, т.е. часть после spring.profiles.active=, до следующего пробела

Для файла:

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

Пример:

% 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 взял бы похожую логику:

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

Пример:

% 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

Обработка ошибок:

В вашем скрипте вы можете использовать случай, когда нет совпадения, другими словами, где ваша исходная строка не содержится spring.profiles.active=. В приведенном выше sedпримере вы получите всю исходную строку, которая может создать проблемы:

% 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

Если вы предпочитаете получать пустую строку при отсутствии совпадений, добавьте -nпараметр в sedкоманду и pпараметр в sed sкоманду, например:

% 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

Затем вы можете проверить, является ли $ var пустым или нет.

heemayl
источник
Спасибо @heemay, работает отлично. теперь мне просто нужно написать это. Я
отмечу
@heemay, ты бы знал, как я мог написать это. У меня есть это в сценарии, и когда он запускается, вернуть QA. Я хочу сохранить результат в переменной с именем env, а затем сравнить это с чем-то вроде. Если [env == qa]; тогда // ДЕЛАЕМ что-то ... еще делаем что-то ...
Гман
1
@Gman Да .. просто используйте подстановку команд: var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"замените file.txtна, <<<'...string...'если ввод - строка, а не файл .. тогда вы можете это сделатьif [ "$var" = 'qa' ]; then do something; else do something; fi
heemayl
1

С помощью awk

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

или

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

пример

% 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
источник
1

Я добавлю Perl один в смеси:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: включает автоматическую обработку конца строки. У него есть два отдельных эффекта. Во-первых, он автоматически запускает $ / (разделитель входных записей) при использовании с -n или -p. Во-вторых, он присваивает $ \ (разделителю выходной записи) значение octnum, чтобы в любом операторе печати этот разделитель был добавлен обратно. Если октнум опущен, устанавливает $ \ текущее значение $ /.
  • -a: включает режим автоматического разделения при использовании с -n или -p. Неявная команда split для массива @F выполняется в качестве первой вещи внутри неявного цикла while, создаваемого -n или -p.
  • n: заставляет Perl принять следующий цикл вокруг вашей программы, который заставляет его перебирать аргументы имени файла, вроде sed -n или awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: может использоваться для ввода одной строки программы.
% <<<'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
кос
источник
Оригинальное регулярное выражение также может быть использовано следующим образом: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