Sed экранирует "." и использует $variable?

Sed экранирует "." и использует $variable?

Я не понимаю этого побега. Есть ли какой-то генератор для этого?

мне нужно заменить обычный текст (185...) на переменную $NEW_DNS

sed -i "185.228.168.168,185.228.169.168|$NEW_DNS /etc/wireguard/wg0.conf

Выход

sed: -e expression #1, char 4: unknown command: `.'

Обновление: у меня есть ответы, которые вы можете видеть, и они работают, просто /etc/wireguard/wg0.conf не перезаписывается новыми данными (но вывод правильный).

# client start menu
echo "What can i do for you today? "
options=("Show Clients" "Show your DNS Server" "Change your DNS Server" "Install/add new Client" "Quit")
select opt in "${options[@]}"
do
    case $opt in
        "Show Clients")
            ls *.conf
            ;;
            "Show your DNS Server")
            if [ $( head -n1 $CONF | awk '{print $5}') == "1.1.1.1,1.0.0.1" ]; then
                echo "Your Public DNS Server is Cloudflare (1.1.1.1,1.0.0.1), great unfiltered choice for best speed worldwide! "
            fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "176.103.130.130,176.103.130.131" ]; then
                echo "Your Public DNS Server is Adguard (176.103.130.130,176.103.130.131), Advertising Filter kill them all! "
            fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "84.200.69.80,84.200.70.40" ]; then
                echo "Your Public DNS Server is WATCH.DNS (84.200.69.80,84.200.70.40), great unfiltered choice for German Clients! "
            fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "9.9.9.9, 149.112.112.112" ]; then
                echo "Your Public DNS Server is QUAD9 (9.9.9.9, 149.112.112.112), great TLS encrypted unfiltered choice! "
            fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "77.88.8.7,77.88.8.3" ]; then
                echo "Your Public DNS Server is Yandex (77.88.8.7,77.88.8.3), safe choice with Family Filter! "
            fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "185.228.168.168,185.228.169.168" ]; then
                echo "Your Public DNS Server is Clean Browsing (185.228.168.168,185.228.169.168), Uuh TLS encrypted safe choice with Family Filter and Youtube-Safe Option! "
                fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "10.8.0.1" ]; then
                echo "Nothing else then own encrypted and logless dedicated DNS Server! "
                 fi
                 ;;
            "Change your DNS Server")
             if [ $( head -n1 $CONF | awk '{print $5}') == "1.1.1.1,1.0.0.1" ]; then
                 echo "Your Public DNS Server is Cloudflare (1.1.1.1,1.0.0.1), great unfiltered choice for best speed worldwide! "
             fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "176.103.130.130,176.103.130.131" ]; then
                 echo "Your Public DNS Server is Adguard (176.103.130.130,176.103.130.131), Advertising Filter kill them all! "
             fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "84.200.69.80,84.200.70.40" ]; then
                 echo "Your Public DNS Server is WATCH.DNS (84.200.69.80,84.200.70.40), great unfiltered choice for German Clients! "
             fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "9.9.9.9, 149.112.112.112" ]; then
                 echo "Your Public DNS Server is QUAD9 (9.9.9.9, 149.112.112.112), great TLS encrypted unfiltered choice! "
             fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "77.88.8.7,77.88.8.3" ]; then
                 echo "Your Public DNS Server is Yandex (77.88.8.7,77.88.8.3), safe choice with Family Filter! "
             fi
               if [ $( head -n1 $CONF | awk '{print $5}') == "185.228.168.168,185.228.169.168" ]; then
                      echo "Your want leave your Clean Browsing server and use another one?. You need generate new configs later, if you want to use new Server (Start Menu choice: 3 ) "
                      # client choice NEW DNS
                          read -rp "Do you really want to change your DNS Server? (y/n) " -e -i y NEW_DNS
                            if [ "$NEW_DNS" == "y" ]; then
                              echo "Which DNS do you want to use with the VPN?"
                                echo "You recognise encrypted DNS with "TLS" (Port 853 can be potentially blocked through Government etc.) Some Servers use logs, but no one of them log aWireguard IP. "
                              echo "   1) Cloudflare: log: yes 24h, Filter: no, + best speed worldwide"
                              echo "   2) AdGuard: Log: yes, Filter: advertising"
                              echo "   3) DNS.WATCH: Log: no, Filter: no, + great speed for Germany"
                              echo "   4) Quad9: TLS: yes, Log: yes, Filter: no"
                              echo "   5) Yandex Family: TLS:no, Log: yes, Filter: adult"
                              echo "   6) Clean Browsing Family: TLS: yes, Log: yes, Filter: adult and explicit sites, Youtube- safe mode"
                              read -p "DNS [1-6]: " -e -i 1 NEW_DNS

                              case $NEW_DNS in
                                  1)
                                      NEW_DNS="1.1.1.1,1.0.0.1"
                                  ;;
                                  2)
                                  NEW_DNS="176.103.130.130,176.103.130.131"
                                  ;;
                                  3)
                                  NEW_DNS="84.200.69.80,84.200.70.40"
                                  ;;
                                  4)
                                  NEW_DNS="9.9.9.9, 149.112.112.112"
                                  ;;
                                  5)
                                  NEW_DNS="77.88.8.7,77.88.8.3"
                                  ;;
                                  6)
                                  NEW_DNS="185.228.168.168,185.228.169.168"
                                  ;;
                              esac
                            fi
                      # EOF client choices DNS
                fi
                sed "s/185\.228\.168\.168,185\.228\.169\.168/$NEW_DNS/" /etc/wireguard/wg0.conf
               if [ $( head -n1 $CONF | awk '{print $5}') == "10.8.0.1" ]; then
                 echo "Nothing else then own encrypted and logless dedicated DNS Server! "
                 fi
                 ;;
        "Install/add new Client")
            break
            ;;
        "Quit")
              exit
            ;;
    esac
done

решение1

Если вы хотите заменить саму строку тем, что у вас есть в переменной:

sed "s|185\.228\.168\.168,185\.228\.169\.168|$NEW_DNS|" /etc/wireguard/wg0.conf

Вам нужно sed s|string|replacement|. Вы можете использовать sed s|string|replacement|gдля замены его во всем файле. Вам также нужно экранировать .с помощью обратной косой черты, чтобы он не представлял собой один символ. Я удалил переключатель -i, чтобы изменения записывались в стандартный вывод, чтобы вы могли убедиться, что это то, что вам нужно. Вы можете вернуть его в команду, как только убедитесь, что это так.

Если вы хотите отредактировать сам файл, добавьте -iпереключатель в свою команду.

sed -i "s|185\.228\.168\.168,185\.228\.169\.168|$NEW_DNS|" /etc/wireguard/wg0.conf

решение2

Команда sв sedделает замену всего, что соответствует заданному регулярному выражению, заданным текстом замены. Ее синтаксис s/expression/text/flags.

В вашем случае вы хотите использовать выражение

185\.228\.168\.168,185\.228\.169\.168

Я экранировал точки, поскольку они являются «специальными» в регулярных выражениях (неэкранированная точка соответствует любому одиночному символу, но вам нужно сопоставить сами точки).

Текст, который вы хотите использовать в качестве текста замены, находится в переменной. Это означает, что все sedвыражение должно быть строкой в ​​двойных кавычках (поскольку оболочка проигнорирует переменную в строке в одинарных кавычках).

Также вам не нужны необязательные флаги с sкомандой здесь, поэтому мы получаем

sed "s/185\.228\.168\.168,185\.228\.169\.168/$NEW_DNS/" filename

Не используйте sed -iфункцию редактирования на месте, пока вы сами не убедитесь, что получен правильный результат.

Обратите внимание, что поскольку мы внедряем значение вашей переменной в скрипт sed, он завершится ошибкой, если $NEW_DNSбудет содержать какие-либо /символы (что, по моему мнению, маловероятно в данном конкретном случае).

Если под запятой вы подразумеваете «либо этот, либо тот адрес», то вам придется использовать чередование (с |):

sed -E "s/185\.228\.168\.168|185\.228\.169\.168/$NEW_DNS/" filename

Я использую его sed -Eздесь, поскольку нам нужно включить расширенные регулярные выражения (они |не являются частью базового синтаксиса регулярных выражений, который используется по умолчанию).

Связанный контент