Почему я должен дважды убежать от «точки»?

13

Я знаю, что мы можем избежать специального символа, такого как *(){}$с, \чтобы считаться литералами.
Например \*или\$

Но в случае .я должен сделать это дважды, в \\.противном случае это считается специальным персонажем. Пример:

man gcc | grep \\.

Почему это так?

зарегистрированный пользователь
источник
Можете ли вы привести случай, что вам нужно сбежать дважды?
Cuonglm
man bash|grep \\.может быть примером.
Зарегистрированный пользователь
3
Точнее, вы дважды не выходите из точки, вы избегаете экранирующего символа, чтобы передать его grep
Ктулху
5
Вы можете использовать кавычки , чтобы избежать побега обратного слэша: man gcc | grep '\.'.
Леонид Бесчастный
1
Я настоятельно предпочитаю @ LeonidBeschastny's предложение, потому что, насколько яснее, что происходит
Иската

Ответы:

24

Как правило, вам нужно всего один раз сбежать, чтобы сделать специальный символ буквальным. Иногда вам приходится делать это дважды, потому что ваш шаблон используется более чем одной программой.

Давайте обсудим ваш пример:

man gcc | grep \\.

Эта команда интерпретируется двумя программами, bashинтерпретатором и grep. Первая причина побега bashзнает \буквально, так что вторая - пропуск grep.

Если вы убегаете только один раз, \., bashбудет знать это точка является буквальным, и перейти .к grep. Когда grepвидишь это ., он думает, что точка - это специальный символ, а не буквальный.

Если бежать в два раза, bashбудет проходить шаблон \.для grep. Теперь grepзнайте, что это буквальная точка.

cuonglm
источник
: Итак, зависит ли экранирующий символ для точки от числа каналов, которые мы используем?. Например, cmd | cmd | cmd | cmd \\\\. Это верно????
Туши
6
@ Thushi: Нет. Это не имеет ничего общего с тем, что вы используете (или несколько) символов канала, но применимо даже для grep \\. my_file. Командная строка интерпретируется оболочкой, используя первую \ для экранирования, а вторая \ передается буквально в grep. Точка .не является особенной для оболочки, поэтому она все равно передается дословно. Grep затем читает (одиночный) \ и использует его, чтобы избежать точки ..
Ансгар Эстерманн
@AnsgarEsztermann: Да. Это правда. Проверено. Спасибо :)
Thushi
2
Я полагаю, что ответ несколько неверен в том смысле, что он говорит: «Первая причина сбоя знает bash. Буквально, вторая - grep». На самом деле, первый выход позволяет bash узнать, что \ leteral, и pass \. grep.
Ктулху
@Gnouc Не думаю, что это так. echo .в баше просто ... перекликается с .характером баха .
Ктулху