开发者

Parse file with BASH script and copy pattern match to a variable

Say I have a file (php as it happens), with a number of variable declarations:

$dbuser = 'fred';
$dppass = 'abc123';
$dhhost = '127.0.0.1';

What I want to do from a BASH script, is parse this file, identify the variables I need, and read their values into variables I can access from my BASH script.

Obviously, the above file being PHP, has other lines that I'm not interested in.

I can extract the info I need from the bash shell using the following command:

grep \$dbuser config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2

which neatly returns

fred

But when I try to add this to a bash script to开发者_如何学编程 put the output into a variable using backticks, as follows:

dbuser=`grep \$dbuser config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2`

my BASH script hangs at this point.

Why is this hanging, or, is there a better way of doing what I'm trying to achieve?


Try it this way:

dbuser=$(grep \$dbuser config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2)

The reason this works and the backticks did not is in the way $(command) handles quoting vs. how the old style backticks handles quoting.

In other words, the following backtick command would have worked just as well:

dbuser=`grep '$dbuser' config.php.inc | grep -Po "'.*'" | cut -d"'" -f 2`
  1. Used single quotes to enclose $dbuser since single quotes means use the literal text rather than interpolate it as a shell variable.
  2. Removed the escaping from .* since it is not needed.
  3. Removed the escaping from the cut command since it is not needed.

BTW, this would have worked as well:

dbuser=`grep '$dbuser' config.php.inc | grep -Po "\'.*\'" | cut -d \' -f 2`

Additionally, the $(command) syntax is in general the best approach whenever possible. Use `` only for portability reasons if you must support a platform that is absolutely known to not support $(command). This is IMHO very rare, so the rule of thumb is to lean towards $(command) from the start.


This will return text like var='value';

awk '
    match($1, /^\$([[:alnum:]_]+)=?/, m){
        gsub(/^[^=]+=[[:space:]]*/, "")
        print m[1] "=" $0
    }
' < file.php

You can eval the output.

update

This is a lot simpler than the above. I realized all you need to do is delete the first $ and remove the spaces around the =:

sed -e 's/\$//' -e 's/ *= */=/' file.php


It sound like that there is a missing \

Check if this is not \\$dbuser

If you have access to perl try:

dbuser=$(perl -ne "print \$1 if /\$dbuser.*'(.*)'/" config.php.inc)

Note : -e use next parameter as a one liner script
-n use all parameter as file argument
print $1 print the matched pattern when matched
The parathesis in the regex define the $1 capture group.


With some basic checking and safety

eval $(sed -n "s/^\$\([a-zA-Z][a-zA-Z0-9_]*\) *= *'\(.*\)' *;/\1='\2';/p")
echo User:$dbuser Pass:$dppass Host:$dhhost

will print for your example

User:fred Pass:abc123 Host:127.0.0.1
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜