Разбор файла с помощью скрипта BASH и копирование совпадения шаблона в переменную - PullRequest
1 голос
/ 30 мая 2011

Допустим, у меня есть файл (php, как это происходит) с несколькими объявлениями переменных:

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

Что я хочу сделать из скрипта BASH, это проанализировать этот файл, определить переменные, которые мне нужны, и прочитать их значения в переменные, к которым я могу получить доступ из моего скрипта BASH.

Очевидно, что в приведенном выше файле PHP есть и другие строки, которые меня не интересуют.

Я могу извлечь необходимую информацию из оболочки bash, используя следующую команду:

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

, который аккуратно возвращает

fred

Но когда я пытаюсь добавить это в скрипт bash, чтобы поместить вывод в переменную с помощью обратных галочек, как показано ниже:

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

Мой BASH-скрипт зависает в этот момент.

Почему это зависание или есть лучший способ сделать то, чего я пытаюсь достичь?

Ответы [ 4 ]

3 голосов
/ 30 мая 2011

Попробуйте так:

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

Причина, по которой это работает, а обратные черты не работали, заключается в том, что $ (команда) обрабатывает кавычки, а не как обратные пометки старого стиля обрабатывают кавычки.

Другими словами, следующая команда backtick работала бы так же хорошо:

dbuser=`grep '$dbuser' config.php.inc | grep -Po "'.*'" | cut -d"'" -f 2`
  1. Использовал одинарные кавычки для включения $ dbuser, так как одинарные кавычки означают использование литерального текста вместо интерполяции его в качестве переменной оболочки.
  2. Удален выход из. * Так как он не нужен.
  3. Удален выход из команды вырезания, поскольку он не нужен.

Кстати, это также сработало бы:

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

Кроме того, синтаксис $ (command), как правило, является наилучшим подходом, когда это возможно. Используйте `` только из соображений переносимости, если вы должны поддерживать платформу, которая, как известно, не поддерживает $ (команда). Это ИМХО очень редко, поэтому эмпирическое правило с самого начала склоняется к $ (команда).

1 голос
/ 30 мая 2011

С некоторыми базовыми проверками и безопасностью

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

напечатает для вашего примера

User:fred Pass:abc123 Host:127.0.0.1
1 голос
/ 30 мая 2011

Это вернет текст как var='value';

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

Вы можете eval вывод.

обновление

Этонамного проще, чем выше.Я понял, что все, что вам нужно сделать, это удалить первый $ и удалить пробелы вокруг =:

sed -e 's/\$//' -e 's/ *= */=/' file.php
1 голос
/ 30 мая 2011

Похоже, что пропал \

Проверьте, не является ли это \\ $ dbuser

Если у вас есть доступ к Perl попробовать:

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

Примечание: -e использовать следующий параметр в качестве однострочного скрипта
-n использовать все параметры в качестве аргумента файла
print $ 1 распечатать совпавший шаблон, когда совпал
Паратезис в регулярном выражении определяет группу захвата $ 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...