Понимание Escaping

Мой источник вопроса – это ответ на эту ссылку , плюс некоторые дополнительные вещи

ОБНОВИТЬ

Я понимаю первую команду, т.е. grep \\[[az\|1-9]*\\] file но я не понимаю вывод второй команды, то есть grep \[[az\|1-9]*\] file ,

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

введите описание изображения здесь

2 Solutions collect form web for “Понимание Escaping”

Пойдем медленно. Если есть файл с этим контентом (всего в одной строке, чтобы упростить его отображение):

 $ cat infile list[1]; i[ab1]; var[1] [1]var [1]var[2] 

Простой grep --color a покажет красным все a. (Так как этот сайт позволяет контролировать цвета: предположим, что полужирный – красный):

 $ grep --color a infile 

list[1]; i[ list[1]; i[ a b1]; v b1]; v a r[1] [1]v a r [1]v a r[2]

Точно так же происходит, если a не цитируется (как указано выше) или если оно указано:

 $ grep --color \a infile 

list[1]; i[ list[1]; i[ a b1]; v b1]; v a r[1] [1]v a r [1]v a r[2]

 $ grep --color "a" infile 

list[1]; i[ list[1]; i[ a b1]; v b1]; v a r[1] [1]v a r [1]v a r[2]

 $ grep --color 'a' infile 

list[1]; i[ list[1]; i[ a b1]; v b1]; v a r[1] [1]v a r [1]v a r[2]

Зачем? Потому что они оба :

  1. Не имеет особого отношения к оболочке.
  2. Оболочка удаляет кавычки, а grep получает тот же самый, что и первый аргумент. Либо обратная косая черта, двойная кавычка, либо одиночная цитата.

]

Если мы хотим выбрать фигурные скобки ] (давайте начнем с закрывающей скобки):

 $ grep --color ] infile 

list[1 ] ; i[ab1 ; i[ab1 ] ; var[1 ; var[1 ] [1 ] var [1 ] var[2 ]

То же самое произойдет, если ] были указаны (любая цитата).
В этом случае ] является особенным для оболочки, но не в этом случае, когда нет подходящей открытой скобки.

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

 grep --color [ infile grep --color '[' infile grep --color "[" infile 

Зачем? Потому что то, что grep получает во всех случаях, является единственным [ .
Вы можете понять, что делает оболочка с этим простым эхом:

  $ echo \[ "[" '[' [ [ [ 

Оболочка удаляет один уровень цитирования, и все значения выглядят одинаково.

[

Но то, что grep хочет получить, чтобы определить, что мы на самом деле ищем персонажа, – это обратная косая квадратная скобка ( \[ ). Это произойдет со всем этим:

 $ echo \\[ "\[" '\[' \[ \[ \[ 

И grep будет работать с любым из них:

 $ grep --color \\[ infile 

list [ 1]; i 1]; i [ ab1]; var ab1]; var [ 1] [ 1]var [ 1]var [ 2]

[[]

Используя [[] (список символов только с одним символом), вы получите тот же результат (пока он цитируется).

 $ grep --color '[[]' infile 

list [ 1]; i 1]; i [ ab1]; var ab1]; var [ 1] [ 1]var [ 1]var [ 2]

Для этого Grep должен получить ровно [[] . Может показаться, что кавычек действительно не нужны:

 $ echo \[\[\] "[[]" '[[]' [[] [[] [[] [[] [[] 

Но если вы создадите файл с именем [ , эта идея сломается:

 $ touch \[ $ echo \[\[\] "[[]" '[[]' [[] [[] [[] [[] [ 

это потому, что [ является специальным для оболочки. В оболочку запускается шаблон подстановки имени файла. Если файл (или многие) соответствует шаблону, то заменяется список файлов.

Итак, это будет работать правильно:

 $ grep --color '[[]' infile 

list [ 1]; i 1]; i [ ab1]; var ab1]; var [ 1] [ 1]var [ 1]var [ 2]

И это: grep --color '[]]' infile будет соответствовать закрывающей скобке.

[] []

Чтобы соответствовать как квадратной скобке открытия, так и закрывающей квадратной скобке, вам нужна определенная последовательность символов (конечно же, цитата).

Если вы попробуете это:

 $ grep --color '[[]]' infile 

Не будет никакого матча, ни одного. Это необходимо для правильной работы:

 $ grep --color '[][]' infile 

list [ 1 ] ; i ; i [ ab1 ] ; var ; var [ 1 ] [ 1 ] var [ 1 ] var [ 2 ]

В этом конкретном порядке закрывающая фигурная скобка должна быть первым символом внутри диапазона символов. Начальная фигурная скобка должна быть последним символом в списке символов.

[] А-z0-9 []

Затем вы можете добавить другие символы (только не ; ):

 $ grep --color '[]a-z0-9[]' infile 

список [1] ; i [ab1] ; вар [1] [1] вар [1] вар [2]

И тогда вы можете добавить недостающие | в диапазоне и выполните матч, который является ссылкой, которую вы опубликовали. Регулярное выражение в этой ссылке не такое же, как здесь, и работает очень по-разному. Он начинается с сопоставления одного [ , некоторых других символов и заканчивается закрытием ] . Нечто похожее (жадная природа * берет всю линию):

 $ grep --color '\[.*\]' infile 

list [1]; я [AB1]; var [1] [1] var [1] var [2]

Или также похоже на это:

 $ grep --color '[[][a-c0-9]*[]]' infile 

list [1] ; i ; i [ab1] ; var ; var [1] [1] var [1] var [2] `

Здесь слишком много переменных и необъявленных предположений, чтобы ответить на ваш вопрос исчерпывающе.

Основная ловушка здесь заключается в том, что оболочка (то есть большинство совместимых с Борном оболочек – не совсем уверенная в zsh или csh и производных) defaut пройдет через glob, нерасширенный, если он ничего не соответствует. Таким образом, выражение, подобное \\[[a-z0-9]*\\] , сначала используется как шаблон. Если нет соответствующих файлов (например, \fno[rd\] где nonalphabbics все буквально), групповой символ передается в grep дословно.

(Давайте рассмотрим это снова. Это двойная обратная косая черта, т. Е. Цитированная буквальная обратная косая черта, сопровождаемая двумя открытыми квадратными скобками. Первый создает класс символов, первым символом которого является второй, литерал [ . Результат разбора этого как регулярного выражение отличается, но аналогично свернуто.)

Единственным разумным решением для этого является правильное цитирование всего, что не нужно подвергать токенизации пробелов и расширению подстановки оболочкой. Моя рекомендация – использовать одинарные кавычки во всех ваших регулярных выражениях. Затем вы сможете сформировать разумное ожидание того, что будет соответствовать и как, без двух экспертных интерпретаций (одна оболочка, одно регулярное выражение) ваших шаблонов.

Если вы пытаетесь полностью сопоставить var[1] , регулярное выражение, подобное [az]*\[[0-9]*\] делает что-то подобное. Если вы хотите, чтобы квадратные скобки были частью класса символов, попробуйте [][a-z0-9]* где первый ] и второй [ являются литеральными членами класса символов. И помните одинарные кавычки вокруг них, если вы передадите их в grep в оболочке.

  • Помещение одной цитаты в имя файла
  • Сохранение вывода команды в переменную в bash приводит к тому, что «Unescaped left brace in regex устарела»
  • bashrc PS1: пользовательская подсказка не очистит весь текст
  • Пробел цвет фона при достижении конца терминала
  • sh -c: Неудачная строка с котировкой строки
  • как правильно планировать задачу, которая планирует задачу с помощью «at» (atd)? или как правильно указывать / бежать в bash
  • Как предотвратить двойное экранирование?
  • Понимание того, что происходит, когда я сбрасываю конечную последовательность символов с помощью Ctrl-v?
  • Квадратный кронштейн квадратной скобки A ^ [[A - Что это значит?
  • Экранирование строк в ассоциативных массивах (bash)
  • печать цветов ansi / escape-кодов с помощью a2ps
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.