Почему grep обрабатывает строку ebug 'по-разному?

Я создал простой текстовый файл с именем «T», чтобы проверить необычное поведение grep :

  1 Debug 2 debug 3 determined 4 Determined 

Пробовал различный синтаксис:

  $ grep De T 1 Debug 4 Determined $ grep de T 2 debug 3 determined $ grep Determined T 4 Determined $ grep determined T 3 determined $ grep Debug T 1 Debug $ grep debug T 2 debug $ grep [D]ebug T # Why result is 2-nd line??? 2 debug $ grep [Dd]ebug T # Why result is only one 2-nd line??? 2 debug $ grep [Dd]e T 1 Debug 2 debug 3 determined 4 Determined $ grep [d]e T 2 debug 3 determined $ grep [d]ebug T 2 debug $ grep "[D]ebug" T 1 Debug $ grep "[Dd]ebug" T 1 Debug 2 debug $ grep [\D]ebug T # Why result is 2-nd line??? 2 debug $ grep --version grep (GNU grep) 2.16 

Как вы можете видеть, почти каждый вызов grep возвращает правильный результат, но $ grep [D]ebug T , $ grep [Dd]ebug T , $ grep [\D]ebug T возвращает неверные результаты. Почему это происходит?

Я предполагаю, что у вас, вероятно, есть файл или каталог, называемый debug в текущем рабочем каталоге:

  $ ls -l total 8 -rw-r--r-- 1 jay wheel 58 Feb 1 05:01 T $ grep [D]ebug T 1 Debug $ grep [Dd]ebug T 1 Debug 2 debug $ touch debug $ ls -l total 8 -rw-r--r-- 1 jay wheel 58 Feb 1 05:01 T -rw-r--r-- 1 jay wheel 0 Feb 1 05:05 debug $ grep [D]ebug T 2 debug $ grep [Dd]ebug T 2 debug 

Я рекомендую вам отличную иллюстрацию, почему вы всегда должны избегать метасимволов оболочки.

Обновите, чтобы уточнить, что происходит . Я предполагаю, что я, как я, использую ОС с файловой системой без учета регистра (например, Mac). Когда вы выполняете команду, ваша оболочка выполняет несколько расширений, прежде чем выполнять grep . Одним из них является расширение имени файла, в котором квадратные скобки обеспечивают чередование:

[Dd]ebug в файловой системе, чувствительной к регистру, будет расширяться до Debug debug , Debug или debug зависимости от того, какие файлы он может сопоставить. Поскольку он только соответствует debug файла, ваша команда стала:

 grep debug T 

Если вы удалите этот файл и touch Debug , вы увидите результат изменения вашей команды, потому что он будет интерполирован как

 grep Debug T 

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