Reputation: 767
I have file settings.inc.php
with the following content:
<?php
define('_DB_SERVER_', 'mariadb');
define('_DB_NAME_', 'organic');
define('_DB_USER_', 'prestashop');
define('_DB_PASSWD_', 'prestashop');
I want to extract these values to bash
, so I managed to create the following command:
sed -rn 's/^.*_DB_NAME_'\'', '\''(\w+)'\''\);/\1/p' settings.inc.php
This will return organic
, just as it should, but I would like to improve it further. Let's say we would have this kind of file:
<?php
define('_DB_SERVER_', 'mariadb');
define('_DB_NAME_', 'organic1');
define('_DB_NAME_', 'organic2');
define('_DB_USER_', 'prestashop');
define('_DB_PASSWD_', 'prestashop');
Using above command on this file we would get:
organic1
organic2
The thing is: I want for this command to always return only one value, so let's say the first one. Can I achieve that without piping result into second command?
Upvotes: 3
Views: 3571
Reputation: 11
Pipe your sed
command to head
and select the first row as show below:
sed -rn 's/^.*_DB_NAME_'\'', '\''(\w+)'\''\);/\1/p' settings.inc.php | head -1
Upvotes: 1
Reputation: 23697
Can also use awk
$ awk -F "'" '$2=="_DB_NAME_"{print $4; exit}' settings.inc.php
organic1
-F "'"
use single quotes as input field separator$2=="_DB_NAME_"
check if second field is _DB_NAME_
print $4
if condition satisfies, print 4th fieldexit
as only first match is neededUpvotes: 2
Reputation: 18697
If you convert your substitute command followed by print to a command block operating only on lines addressed by pattern (containing) _DB_NAME_
, you can quit after the first match/print:
$ sed -rn "/_DB_NAME_/ { s/.*'(\w+)'\);$/\1/p;q }" settings.inc.php
organic1
Note the q
command after p
.
Also, your sed
script can be simplified by using outer double quotes and anchoring on the end.
Upvotes: 0
Reputation: 14520
With GNU grep you could do it:
grep -m1 -Po "_DB_NAME_', '\K[^']+" settings.inc.php
The grep arguments are:
-m 1
: stops the search after 1 match-P
: turns on Perl style regex (so we can use \K
here)-o
: only print the part of the line that matches the patternThe \K
part of the pattern says not to include everything up to that point as part of the match, we then have the rest of the pattern finding everything that's not a '
.
If you wanted to stick with sed
you could find the _DB_NAME_
line, then quit after you found it:
sed -rn '/_DB_NAME/ {s/^.*_DB_NAME_'\'', '\''(\w+)'\''\);/\1/;p;q}' settings.inc.php
which matches _DB_NAME_
then goes into the block that does your s
ubstitution, p
rints the line, then q
uits
Upvotes: 3