sed против массива против переменной

#bash #loops #sed

#bash #циклы #sed

Вопрос:

Есть какой bash -то скрипт, который содержит два массива:

 names=( [0]=port_shutdown
        [1]=port_http
        [2]=port_https
        [3]=keystore_file
        [4]=key_alias
        [5]=keystore_pass
        [6]=truststore_file
        [7]=truststore_pass )

value=( [0]="$port_shutdown"
        [1]="$port_http"
        [2]="$port_https"
        [3]="$keystore_file"
        [4]="$key_alias"
        [5]="$keystore_pass"
        [6]="$truststore_file"
        [7]="$truststore_pass" )
  

И переменные:

 port_shutdown="8008"  
port_http="8046"   
port_https="8446"
keystore_file="tomcat.jks"
key_alias="tomcat"
keystore_pass="password"
truststore_file="trustcacerts.jks"
truststore_pass="password"
  

Запустите его в цикле:

 while [ "$i" -lt "11" ]; do
  name="${names[${i}]}"
  value="${value[${i}]}"
  echo -e "Changing name - "$name" to value "$value";n"
  sed  's|'"${name}"'|'"${value}"'|g' "server.xml.default" > "server.xml"
  (( i   ))
done
  

Но это не меняется names … Хотя — он видит значения в переменных:

 $ ./config.sh
Changing name - port_shutdown to value "8008";

Changing name - port_http to value 8046;

Changing name - port_https to value 8446;

Changing name - keystore_file to value tomcat.jks;

Changing name - key_alias to value tomcat;

Changing name - keystore_pass to value password;

Changing name - truststore_file to value trustcacerts.jks;

Changing name - truststore_pass to value password;
  

Если я задам, например name="port_shutdown" , и value="8008" — это работает хорошо…

Что я здесь делаю не так?

Комментарии:

1. Это выглядит действительно неудобно : value="${value[${i}]}" . Это установило значение нулевого поля массива value в расширение ${value[${i}]} . Конечно, не то, что вы хотите (но без нежелательных эффектов в вашем фрагменте).

Ответ №1:

попробуйте, может быть

 sed  "s|${name}|${value}|g" "server.xml.default" > "server.xml"
  

но он неправильно указывает что-то как разделитель (например: port_http также изменится port_https , если имя массива будет в этом порядке)

Комментарии:

1. Да, это так, это исправит. Спасибо за замечание.

Ответ №2:

Извините, ребята…

Давайте посмотрим, что происходит с sed этим loop :

 sed 's|'"${name}"'|'"${value}"'|g' "server.xml.default" > "server.xml"
  

Итак, он занимает ПЕРВОЕ $name и ПЕРВОЕ $value МЕСТО, берет содержимое server.xml.default , ищет вхождения (совпадения?) в нем замените его, сохраните в файл server.xml . Все в порядке.

Но в следующем цикле — он берет СТАРОЕ server.xml.default , ищет ВТОРОЕ $name и ВТОРОЕ $value , и… Сделайте то же самое — но в новом server.xml он сохранит действие ВТОРОГО цикла, но действие ПЕРВОГО цикла останется неизмененным.

Итак, решение состояло в том, чтобы создать временный файл, который будет сохранять все изменения после каждого цикла:

 i=0
cp server.xml.default server.xml.tmp

while [ "$i" -lt "11" ]; do
  name="${names[${i}]}"
  value="${value[${i}]}"
  echo -e "Changing name - "$name" to value "$value";n"
  sed  's|'"${name}"'|'"${value}"'|g' server.xml.tmp > server.xml
  cp server.xml server.xml.tmp
  (( i   ))
  name=
  value=
done