1

I'd like to write bash script to parse data from a configuration file. I searched for this but without finding something I could modify to suit my needs.

Joomla! config file:

   public $access = '1';
   public $debug = '0';
   public $debug_lang = '0';
   public $dbtype = 'mysqli';
   public $host = 'localhost';
   public $user = 'template';
   public $password = 'template';
   public $db = 'template_druha';
   public $dbprefix = 'dsf1i_';
   public $live_site = '';
   public $secret = '2w9gHzPb4HfAs2Y9';
   public $gzip = '0';
   public $error_reporting = 'default';

I'd like to parse the database credentials on lines with "$user" and "$password" and store them in a variable. What is the best practice?

  • 1
    If your file is PHP, use PHP (or a PHP AST parser). – Chris Down Sep 16 '15 at 16:40
  • Parse the file using awk to extract the $user and $password values from this joomla config file. – steve Sep 16 '15 at 16:42
  • Have php read in and parse the file, then have print statements to return the values you want – roaima Sep 16 '15 at 16:48
2

With GNU grep, you could do:

user=$(grep -oP "\\\$user.+?'\K[^']+" file)
pass=$(grep -oP "\\\$password.+?'\K[^']+" file)

The -P enables Perl Compatible Regular Expressions, which give us \K (ignore anything matched so far). The -o means "only print the matching portion of the line. Then, we search for $var (we need three \, to avoid expanding the variable and to avoid the $ being taken as part of the regex), a single quote and one or more non-' characters until the next '.

Alternatively, you could use awk:

user=$(awk -F"'" '/\$user/{print $2}' file)
pass=$(awk -F"'" '/\$password/{print $2}' file)

Here, we are setting the field delimiter to ', so the value of the variable will be the second field. The awk command prints the second field of matching lines.

1

For your sample input:

$ cat /tmp/foo
public $access = '1';
public $debug = '0';
public $debug_lang = '0';
public $dbtype = 'mysqli';
public $host = 'localhost';
public $user = 'template-user';
public $password = 'template-pass';
public $db = 'template_druha';
public $dbprefix = 'dsf1i_';
public $live_site = '';
public $secret = '2w9gHzPb4HfAs2Y9';
public $gzip = '0';
public $error_reporting = 'default';

You could do:

user="$(grep '$user' /tmp/foo | sed -e 's/  *$//g' -e 's/;$//' | awk -F= '{ print $2}')"
pass="$(grep '$password' /tmp/foo | sed -e 's/  *$//g' -e 's/;$//' | awk -F= '{ print $2}')"
  • The grep searchs for the user or password lines in the given file
  • The first sed expression removes any trailing whitespace
  • The second sed expression removes the trailing ;
  • The awk uses = as the column delimiter, and prints the second column
  • The var=$(...) evaluates all that, takes it output and stores it in the variable
1

Since this file is a PHP file, the most reliable way to extract data for it is to parse it with PHP. If you need to use the data in a shell script, write some PHP code that prints out variable assignments in shell syntax.

#!/bin/sh
eval "$(php -r '
    include $argv[1];
    $config = new JConfig();
    echo "joomla_user=\x27" . preg_replace("/\x27/", "\x27\\\x27\x27", $config->user) . "\x27\n";
    echo "joomla_password=\x27" . preg_replace("/\x27/", "\x27\\\x27\x27", $config->password) . "\x27\n";
' /path/to/configuration.php)"
echo "User is $joomla_user"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.