Недавно у меня возникли проблемы с некоторым регулярным выражением в командной строке, и я обнаружил, что для сопоставления обратной косой черты можно использовать различное количество символов. Это число зависит от цитирования, используемого для регулярного выражения (нет, одинарные кавычки, двойные кавычки). Посмотрите следующую сессию Bash, что я имею в виду:
echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file
Это означает, что:
- без кавычек я могу сопоставить обратную косую черту с 4-7 фактическими
- с двойными кавычками я могу сопоставить обратную косую черту с 3-6 фактическими
- С одинарными кавычками я могу сопоставить обратную косую черту с 2-3 фактическими.
Я понимаю, что одна дополнительная обратная косая черта игнорируется оболочкой (со страницы руководства bash):
«Обратная косая черта без кавычек (\) является escape-символом. Она сохраняет буквальное значение следующего последующего символа»
Это не относится к примерам в одинарных кавычках, потому что в одинарных кавычках не выполняется экранирование.
И еще одна обратная косая черта игнорируется командой grep («\ c» - это просто «c», но это то же самое, что и «c», потому что «c» не имеет специального значения в регулярном выражении).
Это объясняет поведение примера с одинарными кавычками, но я не совсем понимаю другие два примера, особенно почему есть разница между не заключенными в кавычки строками в двойных кавычках.
Опять цитата из справочной страницы bash:
«Заключение символов в двойные кавычки сохраняет буквальное значение всех символов в кавычках, за исключением $,`, \ и, когда расширение истории включено,!. »
Я попробовал то же самое с GNU awk (например awk /ab\cd/{print} file
), с теми же результатами.
Perl, однако, показывает разные результаты (используя, например perl -ne
"/ab\\cd/"\&\&print file
):
- без кавычек я могу сопоставить обратную косую черту с 4-5 фактическими
- с двойными кавычками я могу сопоставить обратную косую черту с 3-4 фактическими
- С одинарными кавычками я могу сопоставить обратную косую черту с двумя фактическими
Может ли кто-нибудь объяснить разницу между строками регулярных выражений без кавычек и двойными кавычками в командной строке для grep и awk? Меня не интересует объяснение поведения Perl, поскольку я обычно не использую однострочные символы Perl.
источник
printf "\ntest"
вставит новую строку перед "тестом", даже если оболочка"\n"
должна была преобразовать"n"
его в двойные кавычки ... (поэтому ожидаемый результат должен быть для "\ ntest", "ntest". У нас должна появиться привычка писать:printf "\\ntest"
илиprintf '\ntest'
, но каким-то образом я вижу множество сценариев, полагающихся вместо этого на странность.По этой ссылке описаны bash Quotes и Escapeing
Ваш вопрос касается первых трех разделов.
Ниже приведен график того, как строки
bash
передаютсяgrep
и какgrep
их интерпретировать внутренне.Давайте сначала посмотрим на
echo "#ab\\cd" > file
.В слабой кавычках ( «»)
"#ab\\cd"
, то\\
это сбежавший ,\
который передается вfile
качестве одного литерала\
. Итак,file
содержитab\cd
Теперь к вашим командам: приведенная ниже таблица может помочь увидеть, что на самом деле происходит с каждым вызовом.
*
Показывает те , которые соответствуют содержимому файла. На самом деле это просто вопрос применения правил эвакуации bash, как на веб-странице, с особой пометкой к ответу Даниэля Куллмана, где он ссылается на экранирование поведения в ситуации слабого цитирования .источник