Extract word from string using grep/sed/awk
Mia Lopez
I have a string
00:28:04 /usr/lib/jvm/jre/bin/java -DJDBC_CONNECTION_STRING= -Dspring.profiles.active=qa -XX:MaxPermSize=256and 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.txtThe 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.
33 Answers
You can use grep with PCRE (-P):
grep -Po 'spring.profiles.active=\K[^ ]+' <<<'.....string.....'spring.profiles.active=will match this substring literally,\Kwill discard the match[^ ]+will select the desired portion i.e. the portion afterspring.profiles.active=, till the next space
For a file:
grep -Po 'spring.profiles.active=\K[^ ]+' file.txtExample:
% 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'
qased 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'
qaHandling 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=256If 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
qaThen you can test if $var is empty or not.
3Using awk
awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' <<<'your_string'or
awk -F"-Dspring.profiles.active=" '{sub(/ .*/,"",$2);print $2}' your_fileExample
% 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 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 1