Почему 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
Ответы
Ответ 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"