Поиск имен переменных в файле шаблона с помощью Bash/Sed/Awk?

Изhttps://www.openbsd.org/faq/faq10.html#Patches:

Upgrade your system to -current and use binary packages

Binary packages for -current snapshots are rebuilt on a regular basis, and these new packages will include any security fixes that were committed. Simply call pkg_add(1) with the -u flag after picking a mirror to get the new files.

Обязательно обновляйте базовую систему.

2
31.01.2020, 00:36
2 ответа

Ваш критерий, по-видимому, соответствует :любому количеству прописных букв или знаков подчеркивания, содержащихся между ${и }.

gawkможет работать для этого самостоятельно,или grepможет упростить часть сопоставления шаблонов (, но впоследствии потребуется дополнительное форматирование ).


ГНУawk:

gawk -v 'RS=[$]{' -F '}' '$1 ~ /^[A-Z_]+$/ && !a[$1]++ {printf "%s=\n", $1}' FILE
  • GNU awk может принимать регулярное выражение для разделителя записей, поэтому, назначив RS=[$]{, он разделит ввод FILEна записи везде, где встречается шаблон ${
  • разделитель полей установлен на }— теперь можно проверить первое поле каждой записи, чтобы увидеть, соответствует ли оно другим вашим критериям :ничего, кроме одного -или -больше из[A-Z_]
  • использование && !a[$1]++удалит дубликаты
  • оператор печати добавляет знак равенства =в конец каждой строки, чтобы соответствовать желаемому результату
  • также обратите внимание :первая часть файла всегда будет считаться первой записью — даже если она не начинается с ${— это означает, что если ваш файл начинается с[A-Z_]+}(маловероятно )- эти прописные буквы/символы подчеркивания будут "совпадать" и будут напечатаны в первой строке вывода

grep+ форматирование

grepвозможно, легче понять (благодаря опции -o/ --only-matching):

grep -o '${[A-Z_]\+}' FILE
  • но это не форматирует вывод :канал через sedможет сделать это :например.
grep -o '${[A-Z_]\+}' FILE | sed 's/${\(.*\)}/\1=/'
  • это не удаляет дубликаты :вывод канала через sort -u, чтобы сделать это, или, альтернативно, один раз через awk:
grep -o '${[A-Z_]\+}' FILE | awk -F '[{}]' '!a[$0]++{printf "%s=\n", $2}'
4
28.04.2021, 23:25

Вот что я в итоге сделал:

cat file | grep -o '${\w*}' | sed -e 's|${||g' -e 's|}|=|g'

DB_HOST=
DB_PORT=
WEB_HOST=
WEB_PATH=

Кажется, это работает достаточно хорошо, даже если выглядит некрасиво!

Или другой метод (, модифицированный по сравнению сhttps://unix.stackexchange.com/a/13467/229729):

cat file | sed -n -e 's/.*${\(\w\+\)}.*/\1=/p'
1
28.04.2021, 23:25

Теги

Похожие вопросы