3

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?

4 Answers 4

3

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 pattern

The \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 substitution, prints the line, then quits

Sign up to request clarification or add additional context in comments.

Comments

2

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 field
  • exit as only first match is needed

Comments

1

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 

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.