Intereting Posts
Как разбить строку – Bash Как предоставить разрешения другому пользователю после регистрации в качестве пользователя root в Linux? Как я могу скомпилировать, установить и запустить инструменты внутри ядра / инструментов? замените шаблон внутри строки с рисунка в начале Как узнать, что находится в сеансе Заблокировать Parted Magic? Почему существует диспропорция в использовании диска, сообщаемая df и du? как сфокусировать различные «регионы» (Ctrl-a S) с помощью мыши в `screen`? Установка разделов Ubuntu Как изменить цвет шрифта / фона в прозрачных окнах? Невозможно подключить USB Wi-Fi к гостевому серверу Kali с помощью Virtual Box Откройте статический IP-адрес подключенного Ethernet-кабеля gui для подрывной работы с kde (kdesvn?) Почему я могу быть уверен, что GNU Parted не испортил ни одного бита после сокращения моего раздела? Как решить странную ошибку при запуске Google Chrome?

Как заменить список заполнителей в текстовом файле?

У меня есть текстовый (конфигурационный) файл, но программа, которая читает файл, к сожалению, не позволяет использовать какие-либо переменные. Поэтому я хотел бы использовать препроцессор, который заменяет набор заполнителей в файле конфигурации, прежде чем передавать его в программу.

Я могу определить формат переменных любым способом (например, §SOME_DIR ). Если бы у меня было всего несколько переменных, я бы, вероятно, использовал sed :

 sed -e "s*§SOME_DIR*$SOME_DIR*g" my.conf | target_prog 

Но список переменных довольно длинный, и его нужно легко настроить – поэтому я бы предпочел поместить переменные в файл свойств, например

 SOME_DIR=... OTHER_DIR=... ... 

а затем позвоните

 some_replace_tool my.properties my.conf | target_prog 

Я ищу «some_replace_tool». Есть идеи?

Я, вероятно, написал бы какой-нибудь скрипт для расширения оболочки varaibles для создания выходного файла конфигурации.

Вот несколько советов:

  1. здесь строки (<<<) расширяются
  2. вы можете загружать переменные с помощью ". varaibles.conf"
  3. env -i script.sh будет запускать скрипт в чистой среде (без дополнительных варочных элементов)

Поэтому скрипту придется построить новый временный скрипт, который будет генерировать переменные и cat here-string с расширенными vars. Затем, чтобы получить окончательный вывод, вам нужно будет запустить этот созданный с временным кодом скрипт через env -i .

У @fred есть что-то вроде правильной идеи, но гораздо более простая система может быть:

 sed -ne '/^#/d;s!^\([^=]*\)=\(.*\)$!s@\1@\2g!p' my.proprties > script.sed sed -f script.sed my.conf | target_prog 

Это также генерируется только для строк, которые имеют «PROP = VALUE» и игнорируют строки комментариев.

Нарушение этого:

 /^#/d - delete any comment lines (to ignore #PROP=VALUE) s!^\([^=]*\)=\(.*\)$ - match any line with PROP=VALUE and place PROG into group 1 and VALUE into group 2 !s@\1@\2@g - replace with s@GROUP1@GROUP2@g !p - print the line, to override the -n 

Вы получаете сценарий sed, похожий на:

 s@PROP1@VALUE1@g s@PROP2@VALUE2@g ... 

Вероятно, самым распространенным и переносимым способом простого расширения макросов является препроцессор C:

 cat my.properties my.conf | cpp -P -DSOME_DIR=/a/b -DOTHER_DIR=/c | target_prog 

Обратите внимание, что здесь вы должны использовать cat , так как cpp принимает только один входной файл в качестве параметра.

Но, как вы написали, что у вас много переменных, вы можете поместить их в файл:

 #define SOME_DIR /a/b #define OTHER_DIR /c 

Затем передайте его в cpp как:

 cat my.properties my.conf | cpp -P -imacros definition.cpp | target_prog 

Существует два препроцессора, которые могут претендовать на традиционные препроцессоры unix: cpp (препроцессор C) и m4 . Ни один из них не подходит для общей предварительной обработки, поскольку они заменяют слова в любом месте текста, а в случае cpp накладывают синтаксис комментария. Разумный общий препроцессор будет иметь индикатор макроса (т. @name Не расширять каждое вхождение name , расширять только @name (например)).

Нет препроцессора, который я бы назвал стандартом де-факто или даже просто обычным. Один, адаптированный к различным форматам ввода и доступный во многих дистрибутивах Linux, – это GPP .

Если вы хотите придерживаться стандартных инструментов, вы можете использовать оболочку в качестве препроцессора в некоторых случаях. Создайте строку, затем запустите

 eval 'preprocessed=$(cat <<EOF) $template EOF' 

Параметры и команды Shell ( $var , $(command) , `command` ) будут расширены. Обратите внимание, что вы не можете легко запретить шаблону вызывать внешние команды или назначать переменные, используемые скриптом, поэтому не используйте это, если вы не доверяете месту, откуда приходит шаблон.

Обновление. Расширяя Arcege sed-to-sed Arcege , вы можете иметь более управляемый макет (табличный или оборванный) для шаблонов find / repl, которые могут быть встроенными … и нет необходимости в промежуточном файле: (добавьте g перед p'<<'EOF' чтобы сделать несколько изменений на строку … Обратите внимание, что foo , barbar и т. д. будут обрабатываться sed как регулярные выражения.

 I=$'\01'; sed -nre "s/^([^ ]+) +/s$I\1$I/;s/$/$I/p"<<'EOF' |sed -f - file foo By the middle of June, barbar mosquitos were rampant, foofoofoo the grass was tawny, a brown dust barbarbarbar haze hung over the valley EOF 

(оригинальное сообщение)
Вы можете использовать sed как исполняемый скрипт с оберткой …

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

Этот скрипт преобразует ваши пары find / repl в sed выражения и динамически создает исполняемый скрипт

 I=$'\01'; set -f printf "#!/bin/sed -f\n" > ~/bin/script.sed while IFS= read -r line ;do ix=$(expr index "$line" " ") printf "s%s%s%s%s%s\n" $I ""${line:0:$((ix-1))}"" $I "${line:$ix}" $I done <<'EOF' >> ~/bin/script.sed $text1 By the middle of June, $text2 mosquitos were rampant, $text3 the grass was tawny, a brown dust $text4 haze hung over the valley EOF chmod +x ~/bin/script.sed 

Это файл теста, который необходимо изменить.
'$' в порядке, так как это не конец строки (для sed), и он никоим образом не будет открыт для оболочки, но любой токен, который не будет сталкиваться с sed , прекрасен. Вы даже можете использовать #

 echo '$text1 $text2 $text3 $text4' > file 

Предполагая, что ~/bin является каталогом $ PATH, команда для запуска:

 script.sed file