У меня есть два файла конфигурации, старый и новый.Новый шаблон конфигурации со значениями по умолчанию и, возможно, дополнительными переменными.Старый измененный конфиг со значениями, которые должны быть сохранены.Мне нужно создать новую модифицированную конфигурацию:
- , если переменная существует как в старой, так и в новой версии, сохранить старое значение
- , если переменная закомментирована в старой, сохранить ее и наоборот.наоборот
- если переменная существует только в старом, удалите его
- , если переменная существует только в новом, сохраните его
старый измененный
$ cat old.cfg
# var1 = 111
# var2 = 123
var3 = 111
var4 = 123
var5 = 123
новая конфигурация по умолчанию
$ cat new_default.cfg
var1 = 111
# var2 = 123
var3 = 111
# var4 = 111
var6 = 111
новая измененная конфигурация (желательно)
$ cat new.cfg
# var1 = 111
# var2 = 123
var3 = 111
var4 = 123
var6 = 111
#
всегда разделяется пробелами (так как редактирование конфигурации выполняется вручную, я использую sed
дляthis: sed -i -E 's/^#([^ ])/# \1/'
), так что, возможно, awk можно использовать для всего этого.На данный момент у меня есть awk 'FNR==NR{a[$1]++;next}!a[$1]' new_default.cfg old.cfg
, который записывает имя переменной (1-й столбец в awk), что является общим для обоих файлов.
========================================================
UPD: Наконец-то я воспользовался приведенным ниже ответом и изменил его, так что теперь он лучше отвечает моим потребностям, а также выглядит уродливее.
- , принимая два аргумента,старый конфиг и шаблон для пропатченного конфига
- , обеспечивающий следующий пробел после
#
в начале строки - , гарантирующий, что каждый
=
окружен одним пробелом с каждой стороны - гарантирует, что каждый фактический комментарий начинается с двух
#
вместо одной - , выдающей команду awk: если строка начинается с
#
-> сравнить второй столбец;начинается с ##
-> сравнить всю строку;начинается без #
-> сравнить первый столбец
.
#!/bin/bash
for var in "$@"
do
cp $var $var.bak
sed -i -E 's/^#([^ ])/# \1/' $var
sed -i -E 's/(.?)(\s?)=(\s?)(.?)/\1 = \4/' $var
sed -i -E 's/^#([^=]+)$/##\1/' $var
done
awk '{if(/^# /)k=$2;else if(/^## /)k=$0;else k=$1;}NR==FNR{a[k]=$0; next}
{print (k in a)?a[k]:$0}' $1 $2 > output.txt