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

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

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

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

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

Пример описания моей ситуации ниже:

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

sed -f replace.txt < a.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

Ответ 1

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

s:?page=one&:pageone:g

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

s/\//foo/

Что заменит / на foo. Вы хотите использовать экранированный обратный слеш в тех случаях, когда вы не знаете, какие символы могут встречаться в строках замены (например, если они являются переменными оболочки).

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

и т.д.

Ответ 5

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

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

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

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

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

$ VALUE=12345/6
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%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 -e s/%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
}

Ответ 6

эта строка должна работать для ваших 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

Ответ 7

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

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

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

Немного, смелые.


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

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

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


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

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

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

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

Параметр

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

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

Ответ 8

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

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

Ответ 9

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

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

var htmlTemplate = "<div style=\\"color:green;\\"></div>";

Ответ 10

Более простой альтернативой является использование AWK, как в этом ответе:

awk '$0="prefix"$0' file > new_file