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.

  • 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 unix.stackexchange.com ? – Tony Adams Nov 12 '15 at 16:23
  • @TonyAdams Yes there have: text-processing questions have been indirectly covered here, 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 and in the duplicate and once here. – kos Nov 13 '15 at 4:17
  • good question! :D – ncomputers May 24 '17 at 15:14
17

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.

  • 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
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
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.