Старый поток, но это повторяющаяся проблема.
Вот решение с использованием bash- mapfile
:
mateus@mateus:/tmp$ cat input.txt
a = $a
b = $b
mateus@mateus:/tmp$ echo a=$a, b=$b
a=1, b=2
mateus@mateus:/tmp$ function subst() { eval echo -E "$2"; }
mateus@mateus:/tmp$ mapfile -c 1 -C subst < input.txt
a = 1
b = 2
Встроенный в bash mapfile
вызывает пользовательскую функцию subst
(см. Опции -C/-c) в каждой строке, считываемой из входного файла input.txt
. Поскольку строка содержит неэкранированный текст, используется eval
его оценки и echo
преобразованного текста в стандартный вывод (-E избегать интерпретации специальных символов).
ИМХО, это гораздо более элегантно, чем любое решение на основе sed/awk/perl/regex.
Другое возможное решение - использовать собственную подстановку оболочки. Это выглядит как более "переносимый" способ не передавать на mapfile
:
mateus@mateus:/tmp$ EOF=EOF_$RANDOM; eval echo "\"$(cat <<$EOF
$(<input.txt)
$EOF
)\""
a = 1
b = 2
Обратите внимание, что мы используем $EOF
чтобы минимизировать конфликтующие здесь документы cat с содержимым input.txt.
Оба примера из: https://gist.github.com/4288846
РЕДАКТИРОВАТЬ: Извините, первый пример не обрабатывает комментарии и пробелы правильно. Я поработаю над этим и выложу решение.
EDIT2: исправление двойного случайного $ eval