Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract a substring matching a pattern from a Unix shell variable

I'm relatively new to Unix shell scripting. Here's my problem. I've used this script...

isql -S$server -D$database -U$userID -P$password << EOF > $test
exec MY_STORED_PROC
go
EOF

echo $test

To generate this result...

Msg 257, Level 16, State 1:
Server 'MY_SERVER', Procedure 'MY_STORED_PROC':
Implicit conversion from datatype 'VARCHAR' to 'NUMERIC' is not allowed.  Use
the CONVERT function to run this query.
(1 row affected)
(return status = 257)

Instead of echoing the isql output, I would like to extract the "257" and stick it in another variable so I can return 257 from the script. I'm thinking some kind of sed or grep command will do this, but I don't really know where to start.

Any suggestions?

like image 962
John M Gant Avatar asked May 20 '09 15:05

John M Gant


People also ask

How do I match a Unix pattern?

The grep filter searches a file for a particular pattern of characters, and displays all lines that contain that pattern. The pattern that is searched in the file is referred to as the regular expression (grep stands for global search for regular expression and print out).

How do I get a substring in Unix?

You can get the substrings from the $BASH_REMATCH array in bash. In Zsh, if the BASH_REMATCH shell option is set, the value is in the $BASH_REMATCH array, else it's in the $MATCH/$match tied pair of variables (one scalar, the other an array).


2 Answers

bash can strip parts from the content of shell variables.

${parameter#pattern} returns the value of $parameter without the part at the beginning that matches pattern.

${parameter%pattern} returns the value of $parameter without the part at the end that matches pattern.

I guess there is a better way to do this, but this should work. So you could combine this into:

% strip the part before the value:
test=${test#Msg }
% strip the part after the value:
test=${test%, Level*}
echo $test

If you're interested in the (return status = xxx) part, it would be:

result=${test#*(result status = }
result=${result%)*}
echo $result

The relevant section of the bash manpage is "Parameter Expansion".

like image 68
fmarc Avatar answered Nov 02 '22 22:11

fmarc


Here is a quick and dirty hack for you, though you should really start learning this stuff yourself:

RC=`tail -1 $test |sed 's/(return status = \([0-9]\+\))/\1/'`
like image 42
Nikolai Fetissov Avatar answered Nov 02 '22 23:11

Nikolai Fetissov