Как заменить строки, содержащие слэши с sed?

У меня есть проект Visual Studio, который разрабатывается локально. Файлы кода должны быть развернуты на удаленном сервере. Единственная проблема заключается в том, что URL-адрес содержит жесткие коды.

Проект содержит URLS, такие как ? Page = one . Чтобы ссылка была действительной на сервере, она должна быть / page / one .

Я решил заменить все URLS в своих кодовых файлах sed до развертывания, но я застрял на косе.

Я знаю, что это не очень хорошее решение, но это просто поможет мне много времени. Общее количество строк, которые я должен заменить, меньше 10. Общее количество файлов, которые необходимо проверить, составляет ~ 30.

Пример, описывающий мою ситуацию, приведен ниже:

Команда, которую я использую:

sed -f replace.txt  b.txt 

replace.txt, который содержит все строки:

 s/?page=one&/pageone/g s/?page=two&/pagetwo/g s/?page=three&/pagethree/g 

a.txt:

 ?page=one& ?page=two& ?page=three& 

Содержимое b.txt после запуска команды sed:

 pageone pagetwo pagethree 

Я хочу, чтобы b.txt содержал:

 /page/one /page/two /page/three 

    Самый простой способ – использовать другой разделитель в линиях поиска / замены, например:

     s:?page=one&:pageone:g 

    Вы можете использовать любой символ в качестве разделителя, который не является частью любой строки. Или вы можете избежать этого с помощью обратной косой черты.

    Команда s может использовать любой символ в качестве разделителя; любой персонаж приходит после использования s . Я был воспитан, чтобы использовать # . Вот так:

     s#?page=one&#/page/one#g 

    Очень полезным, но менее известным фактом о sed является то, что знакомая команда s/foo/bar/ может использовать любую пунктуацию, а не только косые черты. Общей альтернативой является [email protected]@[email protected] , из которой становится очевидным, как решить вашу проблему.

    добавить \ перед специальными символами

      s/\?page=one&/page\/one\//g 

    и т.д

    эта строка должна работать для ваших 3-х примеров:

     sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' a.txt 
    • Я использовал -r чтобы сохранить некоторое ускорение.
    • линия должна быть общей для вашего, двух трех случаев. вам не нужно делать суб 3 раза

    тест с вашим примером (a.txt):

     kent$ echo "?page=one& ?page=two& ?page=three&"|sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' /page/one /page/two /page/three 

    В системе, которую я разрабатываю, строка, которую нужно заменить sed, представляет собой текст ввода от пользователя, который хранится в переменной и передается в sed.

    Как отмечалось ранее на этом посту, если строка, содержащаяся в командном блоке sed, содержит фактический разделитель, используемый sed – тогда sed завершает синтаксическую ошибку. Рассмотрим следующий пример:

    Это работает:

     $ VALUE=12345 $ echo "MyVar=%DEF_VALUE%" | sed -es/%DEF_VALUE%/${VALUE}/g MyVar=12345 

    Это нарушает:

     $ VALUE=12345/6 $ echo "MyVar=%DEF_VALUE%" | sed -es/%DEF_VALUE%/${VALUE}/g sed: -e expression #1, char 21: unknown option to `s' 

    Замена разделителя по умолчанию не является надежным решением в моем случае, поскольку я не хотел ограничивать пользователя вводом определенных символов, используемых sed в качестве разделителя (например, «/»).

    Однако устранение любых вхождений разделителя во входной строке могло бы решить проблему. Рассмотрим приведенное ниже решение систематического экранирования символа разделителя во входной строке перед его анализом sed. Такое экранирование может быть реализовано как замена с помощью sed, эта замена безопасна, даже если входная строка содержит разделитель – это потому, что входная строка не является частью блока команды sed:

     $ VALUE=$(echo ${VALUE} | sed -e "s#/#\\\/#g") $ echo "MyVar=%DEF_VALUE%" | sed -es/%DEF_VALUE%/${VALUE}/g MyVar=12345/6 

    Я преобразовал это в функцию, которая будет использоваться различными скриптами:

     escapeForwardSlashes() { # Validate parameters if [ -z "$1" ] then echo -e "Error - no parameter specified!" return 1 fi # Perform replacement echo ${1} | sed -e "s#/#\\\/#g" return 0 } 

    sed – это s sream itor , в котором вы можете использовать | (pipe) для отправки стандартных streamов (STDIN и STDOUT специально) через sed и изменять их программно «на лету», что делает его удобным инструментом в философии философии Unix; но также можно редактировать файлы напрямую, используя параметр -i упомянутый ниже.
    Рассмотрим следующее :

     sed -i -e 's/few/asd/g' hello.txt 

    s/ используется для определения найденного выражения few с помощью asd :

    Немного, храбрые.


    Адд, храбрый.

    /g означает «глобальный», что означает сделать это для всей строки. Если вы оставите параметр /g (с помощью s/few/asd/ , всегда должно быть три слэша, независимо от того, что), и few отображаются дважды в одной строке, только первые few изменятся на asd :

    Немногие мужчины, немногие женщины, храбрые.


    Мужчины-ас, немногие женщины, храбрые.

    Это полезно в некоторых случаях, например, для изменения специальных символов в начале строк (например, для замены символов большего, чем некоторые люди используют для цитирования предыдущего материала в streamах электронной почты с горизонтальной вкладкой, оставляя при этом цитированное алгебраическое неравенство позже в строке нетронутый), но в вашем примере, где вы указываете, что где-нибудь few встречаются, он должен быть заменен, убедитесь, что у вас есть /g .

    Следующие два параметра (флаги) объединяются в один, -ie :

    -i используется для редактирования i n в файле hello.txt .

    -e указывает на выполнение команды e xpression / command, в данном случае s/ .

    Примечание. Важно, чтобы вы использовали -i -e для поиска / замены. Если вы сделаете -ie , вы создадите резервную копию каждого файла с прилагаемой буквой «e».

    replace.txt должно быть

     s/?page=/\/page\//g s/&//g е s/?page=/\/page\//g s/&//g 

    Отличный ответ от анонимного. \ решил мою проблему, когда я попытался избежать кавычек в строках HTML.

    Поэтому, если вы используете sed для возврата некоторых HTML-шаблонов (на сервере), используйте двойную обратную косую черту вместо одиночной:

     var htmlTemplate = "
    ";
    Давайте будем гением компьютера.