LINUX.ORG.RU

sed внутри sed и переменная

 , , , ,


0

1

Подскажите как верно решить задачу

есть входной файл вида

103.215.223.226:1080
104.248.63.15:30588
106.14.76.134:1080
106.116.83.52:38801
......

есть несколько ini конфигов вида, каждый в своей директории
proxy_address=
proxy_port= 

В нём значения вида ip и порт и разделитель.
Хочу всё что слева от разделителя вставить в proxy_address
А всё, что справа вставить в proxy_port
Конфигов c директориями несколько, хочу в чтобы в каждом было свой прокси
Всё, что я пока придумал - это построчно считать входной файл и вставить значения, пробую делать это так
#!/bin/bash

input=in.txt
q=1
while IFS= read -r line
do

  sed -i "67s/.*/proxy_address=$sed 's/\:[0-9]*//' "${!input}"/g"  /home/$q/settings.ini
  
  sed -i "68s/.*/proxy_port=$grep -oP '(?<=:)\w+' "${!input}"/g"   /home/$q/settings.ini

((++q))
done < "$input"

но получаю только «bad substitution»
понимаю, что это не изящное решение и велосипед, но пока ничего другого не придумал
может есть способы проще, а главное рабочие?)

★★★★★

В цикл, думаю, сам сможешь положить

echo "103.215.223.226:1080
104.248.63.15:30588
106.14.76.134:1080
106.116.83.52:38801" | sed 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\):\([0-9]\+\)/proxy_address=\1\nproxy_port=\2/g'

proxy_address=103.215.223.226
proxy_port=1080
proxy_address=104.248.63.15
proxy_port=30588
proxy_address=106.14.76.134
proxy_port=1080
proxy_address=106.116.83.52
proxy_port=38801

Kroz ★★★★★ ()
Ответ на: комментарий от gedisdone

конструкция интересная, но она заменяет всё в выходных файлах, вместо изменения только нужных строк, как её поправить не осилил

подскажите возможно ли использование sed внутри sed?
я видел много примеров, но не встречал ещё ничего,чтобы подошло

sed -i "67s/.*/proxy_address="$(sed 's/\:[0-9]*//' in.txt)"/g"  settings.ini

smilessss ★★★★★ ()
Ответ на: комментарий от smilessss

спасибо, эта магия с #!/usr/bin/awk -f и system(«sed работает

Но вот только смысла в этом никакого. Когда awk используется только для разбивки входной информации по двум полям, а внутри этого вызывается system(sed), это означает только одно, что человек не знает ни bash ни awk.

Подсказка. для чтения ip:port надо всего-то IFS=: ; read ip port

vodz ★★★★★ ()
Ответ на: комментарий от vodz

ну мне главное что задача решена
не думаю, что есть более простое решение, чем что-то вроде
Там сложность была в том, что без вложеных sed не получалось простым способом спарсить данные из входного файла и раскидать их по выходным файлам в нужном не формате

#!/usr/bin/awk -f
BEGIN { FS = ":" }
{
  file = "./" NR "/settings.ini";
 
  system("sed -i \"66s/.*/proxy=true/g\" " file);
  system("sed -i \"67s/.*/proxy_address=" $1 "/g\" " file);
  system("sed -i \"68s/.*/proxy_port=" $2 "/g\" " file);
}

smilessss ★★★★★ ()
Ответ на: комментарий от smilessss

Там сложность была в том, что без вложеных sed не получалось

У вас не вложенные, а последовательные, причем последовательное оно только в общем виде, когда если б вы зачем-то захотели вначале исправить параметр на строке ниже, чем в следующем вызове, а для ваших 66-68 всё можно записать в одном вызове sed-а. А я речь вел о том, что если вся программа есть вызывалка system(), что по сути вызывалка опять же через bash, то awk тут не нужен, распарсилку вашего входного файла почти написали, просто не знаете bash-а, когда простой заменой IFS= read line на IFS=: read ip port задача решается с последующим вызовом sed-а банально.

vodz ★★★★★ ()