for j in `cat server_name_list`; do sed -i 's/DIR/${j}/g' dlist1 > $j.conf; done
В основном я пытаюсь создать несколько виртуальных хостов apache, используя один файл виртуального хоста в качестве шаблона....
Итак, файл шаблона: кошка /tmp/dlist1
Allow From All
DocumentRoot /var/www/html/DIR
ServerName DIR.com
ServerAlias www.DIR.com
DirectoryIndex index.html index.htm
ErrorLog "logs/DIR_com_error_log"
CustomLog "logs/DIR_com_access_log" common
И список серверов находится в файле
cat /tmp/server_name_list
abc.com
xyz.com
utv.com
поэтому скрипт sed должен дать мне три файла, как в abc.conf, xyz.conf, utv.conf
с этим содержанием (просто напишите здесь для «abc»):
Allow From All
DocumentRoot /var/www/html/abc
ServerName abc.com
ServerAlias www.abc.com
DirectoryIndex index.html index.htm
ErrorLog "logs/abc_com_error_log"
CustomLog "logs/abc_com_access_log" common
🤔 А знаете ли вы, что...
С Bash можно создавать условные выражения и скрипты, которые реагируют на различные события.
Ну вот:
for j in `cat server_name_list`; do
j = "${j%.*}"
sed "s/DIR/$j/g" dlist1 > $j.conf;
done
Объяснение:
j = "${j%.*}
использует расширение параметра, чтобы удалить расширение .com
из имени сервера. Синтаксис ${j%.*}
означает удаление кратчайшего совпадения .*
(т. е. «.com») с конца строки j
.sed "s/DIR/$j/g" dlist1 > $j.conf
заменяет все вхождения строки DIR
в файле шаблона dlist1 на текущее имя сервера j
sed
перенаправляется в файл с именем $j.conf
.Надеюсь, это поможет 👍
Сначала ты DRLWF
Решение с петлей while
+ read
. Что-то вроде:
#!/usr/bin/env bash
while IFS= read -ru "$fd" servers; do
sed "/^\(ServerName\) .*/s//\1 $servers/" dlist1 > "${servers%.*}"
done {fd}< server_name_list
exec {fd}<&-
Я бы использовал GNU AWK
для этой задачи следующим образом, пусть temp.txt
контент будет
Allow From All
DocumentRoot /var/www/html/DIR
ServerName DIR.com
ServerAlias www.DIR.com
DirectoryIndex index.html index.htm
ErrorLog "logs/DIR_com_error_log"
CustomLog "logs/DIR_com_access_log" common
и list.txt
содержание быть
abc.com
xyz.com
utv.com
затем
awk 'BEGIN{FS = "[.]";RS = "";getline template < "temp.txt";RS = "\n"}{print gensub(/DIR/,$1,"g",template) > $1 ".conf";close($1 ".conf")}' list.txt
создает файлы
abc.conf
utv.conf
xyz.conf
содержание 1-го из них
Allow From All
DocumentRoot /var/www/html/abc
ServerName abc.com
ServerAlias www.abc.com
DirectoryIndex index.html index.htm
ErrorLog "logs/abc_com_error_log"
CustomLog "logs/abc_com_access_log" common
Объяснение: я сообщаю GNU AWK
, что буквенная точка является разделителем полей (FS
), затем я отключаю режим абзаца, устанавливая RS
пустую строку, но только во время использования getline , чтобы он читал все до первой пустой строки, затем я установите RS
на новую строку, чтобы это работало обычным образом. Затем для каждой строки я использую функцию gensub, мне не нужна там группа захвата, но я использую ее, поскольку хочу, чтобы значение переменной template
оставалось нетронутым, после замены всех (g
) DIR
вхождений значением 1-го столбца я print
это в файл с соответствующим именем и close
этот файл.
(проверено в GNU Awk 5.0.1)
Это может сработать для вас (GNU sed и parallel):
parallel sed 's/DIR/{.}/g' templateFile \> {.}.conf :::: serversFile
Для каждой строки в файле серверов примените изменения к файлу шаблона и сохраните результаты в отдельном файле.
Н.Б. {.}
возвращает строку из файла серверов за вычетом расширения, например. abc.com
становится abc
.