Подтвердить что ты не робот

Почему sed требует 3 обратных косых черт для регулярной обратной косой черты?

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

EDIT: вот пример моего компьютера с Windows, используя Cygwin:

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

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

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

Ответ 1

Я смог воспроизвести это поведение с помощью Vista и Cygwin 1.7.0.

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

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

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

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

\\\/ -> \\/

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

\\\\/ -> \\/ 

Edit:

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

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

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

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

Ответ 4

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

$ 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 на окнах, используя 2 слэша

например,

C:\test>echo "sample_input\whatever" | sed "s/\\/\//"
"sample_input/whatever"

Ответ 5

В моей версии 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

Ммм..

Ответ 6

Я предполагаю, что вы принимаете \\\n или \\\t в виде трех обратных косых черт, но на самом деле его две обратные косые черты и другие паттерны

   backslash          \\
   newline            \n
   tab                \t

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

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

Ответ 7

Замена одной обратной косой черты двумя на моем Cygwin требует этого выражения:

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