Почему для регулярной обратной косой черты sed требуется 3 обратной косой черты? - PullRequest
41 голосов
/ 03 марта 2010

Мне любопытно, зачем sed нужно 3 \, чтобы узнать его? Я бы понял, что нужно 2, а 3 - нет.

РЕДАКТИРОВАТЬ: вот пример на моем компьютере с Windows, используя Cygwin:

echo "sample_input\whatever" | sed "s/\\\/\//"

Если я не добавлю 3 обратных слеша, я получу

sed: -e expression #1, char 7: unterminated s' command

Ответы [ 7 ]

41 голосов
/ 03 марта 2010

Мне удалось воспроизвести это поведение с помощью Vista и Cygwin 1.7.0.

  • Два обратных слеша дают ошибку
  • либо три или четыре обратные косые черты работают
  • Пять выдает ту же ошибку

Два обратных слеша становятся единым обратным слэшем в оболочке, который затем в седе избегает прямого слэша, который является средним разделителем.

\\/ -> \/ (which makes the forward slash a regular character instead of a delimiter)

Три из них: первые два становятся одним в оболочке, которые затем выходят из третьего в седле

\\\/ -> \\/

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

\\\\/ -> \\/ 

Edit:

О, я забыл сказать, что одинарные и двойные кавычки работали для меня одинаково (cmd.exe не делает различий, которые делают Bash и др.).

12 голосов
/ 03 марта 2010

Ваша оболочка (вероятно, bash) делает свой собственный выход, и это вас смущает.Вы можете использовать команду echo для просмотра того, что передается, или вы легко можете написать собственную программу (обычно называемую «showargs» или аналогичную):

$ echo "s/\\\/\//"
s/\\/\//
$ echo "s/\\/\//"
s/\/\//

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

6 голосов
/ 20 июня 2014

Это связано с правилом парсинга строк в двойных кавычках sh.

Posix указывает, как sh анализирует строки в двойных кавычках.

Обратная косая черта должна сохранять свое особое значение в качестве escape-символа (см. Escape-символ (Обратная косая черта)) только в том случае, если за ним следует один из следующих символов, если он считается специальным: $ `" \

Другими словами, sh оставляет обратную косую черту, за которой следуют символы, отличные от $ '".

Итак, если sh встречает строку в двойных кавычках sed "s/\\\/\//", sh анализирует ее следующим образом.

  1. Первые два \\ заменены на \. Потому что за первым \ следует второе \.
  2. Третий и четвертый \ все еще остаются в строке. Потому что за ними следует /, что не является особенным в двойных кавычках.

После вставки sh передает строку s/\\/\// в sed, которая заменяет первое вхождение \ на /.

С тем же рассуждением, когда sh встречает строку, "sed s/\\\\/\//", sh передает /\\/\// в sed, что также заменяет первое вхождение \ на /.

4 голосов
/ 03 марта 2010

Пожалуйста, покажите пример того, что у вас есть в будущем. скажем, в sed вы хотите заменить "\" на pipe (|), например

$ cat file
asklfja \ asf

$ sed 's/\\/|/g' file
asklfja | asf

$ sed 's%\\%|%g' file #using different delimiter
asklfja | asf

тебе просто нужно сбежать один раз.

Редактировать: к примеру @ OP, поскольку вы используете cmd.exe, а не bash / ksh, cmd.exe не любит одинарные кавычки Я не могу представить ваш сценарий. Это работает для моего GNU sed на Windows, используя 2 слеша

например

C:\test>echo "sample_input\whatever" | sed "s/\\/\//"
"sample_input/whatever"
1 голос
/ 15 октября 2010

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

$ echo "sample_input\whatever" | sed 's/\\/\//'
sample_input/whatever
$ echo "sample_input\whatever" | sed "s/\\/\//"
sed: -e expression #1, char 7: unterminated `s' command

Хм ..

0 голосов
/ 30 ноября 2012

Для замены одного обратного слеша на два на моем Cygwin требуется следующее выражение:

sed -e "s | \\ | \\\\ | g"

0 голосов
/ 03 марта 2010

Полагаю, вы предполагаете \\\n или \\\t как три обратных слеша, но на самом деле это 2 обратных слеша и еще один шаблон

   backslash          \\
   newline            \n
   tab                \t

также, / может потребоваться убежать, потому что в s/.../, / использует для открытия и закрытия деталей.

поэтому /\\\/\// будет \\ + \/ + \/ в соответствии с вашим обновленным примером

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...