можно сделать 2 вещи..
С zsh
:
print -r -- "${(e)$(<reports/my_report.sql)}"
С любой подобной Границе оболочкой (включая zsh
):
eval "cat << EOF
$(cat reports/my_report.sql)
EOF"
Оба расширятся весь `...`
, $(...)
, $((...))
, $[...]
, $xxx
и ${xxx}
. Таким образом, необходимо будет выйти из доллара и символов обратной галочки, Вы не хотите расширенный.
Кроме того, для второго, содержание файла не должно содержать строку, состоящую из этих трех символов EOF
(который для SQL
не должна быть проблема).
С другой стороны, Вы могли сделать:
perl -pe 's/\${(\w+)}/$ENV{$1}/g' reports/my_report.sql
Вы должны будете export
переменные, для perl
знать о них.
Относительно того, почему Ваше решение не работает и далеко не работает, можно выполнить его после set -x
для наблюдения, что продолжается:
$ echo "SELECT ${sql_year} AS year" | sed -e "s/\(\${[a-zA-Z_]*}\)/`eval "echo '\1'"`/"
+ echo 'SELECT 2013 AS year'
++ eval 'echo '\''\1'\'''
+++ echo '\1'
+ sed -e 's/\(${[a-zA-Z_]*}\)/\1/'
SELECT 2013 AS year
При помощи двойных кавычек оболочка разворачивает переменные и замену команды перед вызовом echo
и sed
. Так, Вы на самом деле работали:
echo 'SELECT 2013 AS year' | sed -e 's/\(${[a-zA-Z_]*}\)/\1/'
sed
не может выполнить код. Таким образом, даже если Вы использовали одинарные кавычки, sed
не расширился бы `...`
.
Я позволил бы Bash интерполировать значения для Вас вместо того, чтобы пытаться записать регулярное выражение, чтобы сделать то же (или усилить некоторую систему шаблонной обработки).
echo $(eval echo $(cat sql.sql))
Где sql.sql содержит допустимую строку удара (поэтому монтируйте в корпус его в двойных кавычках):
"SELECT
(SELECT COUNT(*) FROM metrics WHERE(organization_id = o.id AND year = ${sql_year})) AS metrics,
(SELECT COUNT(*) FROM my_metrics WHERE(organization_id = o.id)) AS quarterly_metrics,
(SELECT COUNT(*) FROM quarterly_metrics WHERE(organization_id = o.id AND year = ${sql_year})) AS quarterly_metrics,
(SELECT COUNT(*) FROM quarterly_text_metrics WHERE(organization_id = o.id AND year = ${sql_year})) AS quarterly_text_metrics,
(SELECT COUNT(*) FROM budgets WHERE(organization_id = o.id AND year = ${sql_year})) AS budgets,
(SELECT COUNT(*) FROM goals WHERE(goalable_type = 'Organization' AND goalable_id = o.id AND year = ${sql_year})) AS goals
FROM
organizations AS o
WHERE
o.id = ${sql_org_id}
;"
zsh
, и я получаю следующую ошибку: zsh: no matches found: (SELECT COUNT(*) FROM metrics WHERE(organization_id = o.id AND year = 2013))
– Vance Lucas
01.08.2013, 04:39
Что, если Вы меняете свой подход так, чтобы Вы сделали это вместо этого:
$ heroku pg:psql --app app_name < file.sql
perl
решение, потому что это, намного более вероятно, будет то же, неважно, какая система на этом работают. – Vance Lucas 01.08.2013, 18:11