12

I have a string

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

and want to extract the word qa that follows -Dspring.profiles.active.

I have the string save in a file text.txt just to demo on it.

When I do

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

The result is spring.profiles.active=

This word does not always be qa, it could be prod or dev.

What I'd like to do is find the word spring.profiles.active and after the = extract that word.

I would like to shell script this because I use the word to configure other items on the server.

Is this possible and if so, how do I do it.

A.B.
  • 89,123
  • 21
  • 245
  • 323
Gman
  • 481
  • 3
  • 7
  • 17
  • I'm guessing there have been meta conversations about this already, but this question is completely non-specific to Ubuntu. Why is it here instead of http://unix.stackexchange.com/ ? – Tony Adams Nov 12 '15 at 16:23
  • @TonyAdams Yes there have: text-processing questions have been indirectly covered [here](http://meta.askubuntu.com/questions/14123/is-ask-ubuntu-about-solving-actual-problems), and anyway de-facto they have been always considered on-topic and never closed / migrated; on the Ubuntu-specificness, that has been covered multiple times, twice just recently [here](http://meta.askubuntu.com/questions/14663/are-non-ubuntu-spefic-questions-allowed) and in the duplicate and once [here](http://meta.askubuntu.com/questions/47/how-do-we-tell-if-a-question-belongs-here-or-rather-at-stackoverflow-superuser). – kos Nov 13 '15 at 04:17
  • good question! :D – ncomputers May 24 '17 at 15:14

3 Answers3

20

You can use grep with PCRE (-P):

grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'
  • spring.profiles.active= will match this substring literally, \K will discard the match

  • [^ ]+ will select the desired portion i.e. the portion after spring.profiles.active=, till the next space

For a file:

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

Example:

% 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 would take similar logic:

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

Example:

% 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

Handling errors:

In your script you may want to handle the case where there is no match, in other words where your original string does not contain spring.profiles.active=. In the above sed example, you obtain the whole original string, which could create problems:

% 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

If you prefer to obtain the empty string when there is no match, add the -n option to the sed command and the p option to the sed s command, like this:

% 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

Then you can test if $var is empty or not.

Law29
  • 135
  • 4
heemayl
  • 90,425
  • 20
  • 200
  • 267
  • Thanks @heemay, works perfect. now I just need to script that. I will mark it as answered – Gman Nov 12 '15 at 11:34
  • @heemay would you know how I could scripted this. I have it in a script and when it runs it return qa. I want to save the result in a variable called env and then to compare that to something like. If [ env == qa ]; then //DO Something... else Do Something... – Gman Nov 12 '15 at 12:04
  • 1
    @Gman Yeah.. just use command substitution: `var="$(grep -Po 'spring.profiles.active=\K[^ ]+' file.txt)"` replace `file.txt` with `<<<'...string...'` if input is a string, not a file..then you can do `if [ "$var" = 'qa' ]; then do something; else do something; fi` – heemayl Nov 12 '15 at 12:08
1

Using awk

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

or

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

Example

% 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
A.B.
  • 89,123
  • 21
  • 245
  • 323
1

I'll throw a Perl one in the mix:

<<<'string' perl -lane '$F[3]=~s/.*?=//;print($F[3])'
  • -l: enables automatic line-ending processing. It has two separate effects. First, it automatically chomps $/ (the input record separator) when used with -n or -p. Second, it assigns $\ (the output record separator) to have the value of octnum so that any print statements will have that separator added back on. If octnum is omitted, sets $\ to the current value of $/.
  • -a: turns on autosplit mode when used with a -n or -p. An implicit split command to the @F array is done as the first thing inside the implicit while loop produced by the -n or -p.
  • n: causes Perl to assume the following loop around your program, which makes it iterate over filename arguments somewhat like sed -n or awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
    
  • -e: may be used to enter one line of program.
% <<<'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
  • 35,535
  • 13
  • 101
  • 151
  • orginal regex can be used also like this: `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 Nov 12 '15 at 15:40