Чтение переменных без bash из файла в скрипт bash

Мой скрипт bash должен читать переменные из текстового файла, содержащего сотни переменных, большинство из которых соответствуют стандартному синтаксису переменных bash (например, VAR1=VALUE1 ). Однако несколько строк в этом файле могут быть проблематичными, и я надеюсь найти простое решение для их чтения в bash.

Вот как выглядит файл:

 #comment VAR1=VALUE1 VAR_2=VALUE_2 ... VAR5=VALUE 5 (ASDF) VAR6=VALUE 6 #a comment VAR7=/path/with/slashes/and,commas VAR8=2.1 VAR9=a name with spaces VAR_10=true ... VAR_N=VALUE_N 

Правила файловой структуры включают:

  • одна переменная (со значением) на строку
  • присваивание (=) не имеет пробелов вокруг него
  • имя переменной находится в первом столбце (если это не строка комментария)
  • комментарии могут следовать за значением (после #)
  • значения могут включать пробелы, парсеры, косые черты, запятые и другие символы
  • значения могут быть числами с плавающей запятой (2.1), целыми числами, истинными / ложными или строками.
  • строковые значения не указаны, и они могут быть длиной в тысячу символов длинными или длинными
  • имя переменной содержит только буквы и подчеркивания UPDATE: и числа .

Большинство переменных имеют тип, который просто позволит мне загрузить файл в мой сценарий bash. Но эти немногие проблематичные диктуют другое решение. Я не уверен, как их читать.

2 Solutions collect form web for “Чтение переменных без bash из файла в скрипт bash”

Хотя вы можете превратить этот файл в фрагмент оболочки, это сложно. Вы должны убедиться, что все специальные символы оболочки указаны правильно.

Самый простой способ сделать это – поставить одинарные кавычки вокруг значения и заменить одиночные кавычки внутри значения на '\'' . Затем вы можете поместить результат во временный файл и указать этот файл.

 script=$(mktemp) sed <"config-file" >"$script" \ -e '/^[A-Z_a-z][A-Z_a-z]*=/ !d' \ -es/\'/\'\\\\\'\'/g \ -es/=/=\'/ -es/\$/\'/ 

Я рекомендую делать синтаксический разбор непосредственно в оболочке. Сложность кода примерно одинакова, но есть два основных преимущества: вы избегаете необходимости в временном файле и риск того, что вы случайно получили неверную цитату и в конечном итоге выполните часть строки в виде фрагмента оболочки ( что-то вроде dangerous='$(run me)' ). Вы также получаете больше шансов на проверку потенциальных ошибок.

 while IFS= read -r line; do line=${line%%#*} # strip comment (if any) case $line in *=*) var=${line%%=*} case $var in *[!A-Z_a-z]*) echo "Warning: invalid variable name $var ignored" >&2 continue;; esac if eval '[ -n "${'$var'+1}" ]'; then echo "Warning: variable $var already set, redefinition ignored" >&2 continue fi line=${line#*=} eval $var='"$line"' esac done <"config-file" 

Предполагая, что ваше содержимое находится в файле x.txt , вы можете использовать выражение sed :

 sed -e 's/#.*//' -e 's/=.*$/="&"/g' -e 's/=//2' x.txt 

Первое выражение ставит все после знака = в кавычках. Второе выражение удаляет знак extra = а третье выражение удаляет все между # и " поскольку они являются комментариями.

Следующее приведет к цитированию RHS в одинарные кавычки:

 sed -e "s/#.*//" -e "s/=.*$/='&'/g" -e "s/=//2" x.txt 
  • Установка переменной, значение которой зависит от другой переменной
  • Как назначить вывод команды переменной без запуска команды в подоболочке?
  • Объем переменных при вызове функции из find
  • Создать переменную на основе порядка, в котором файл находится в алфавитном списке файлов
  • Область переменных в while-read-loop на Solaris
  • dirname и basename против расширения параметров
  • Как сохранить статус последнего выхода после теста
  • Переменные баша в команде
  • Разделить команду и аргументы и вставить в переменную в сценарий bash
  • Отложить переменное расширение до подоболочки
  • Как изменить переменные
  • Linux и Unix - лучшая ОС в мире.