Яка різниця між "* .pl" та * .pl у grep? Чому цитування змінює результат?


10

Яка різниця між:
grep "string" . -r --include *.pl

і

grep "string" . -r --include "*.pl"

Останній включає файли в підкаталозі, а перший - ні. Чому?


Різниця не в тому grep; це в оболонці. grepніколи не бачить цитат.
Wildcard

Відповіді:


17

*(Зірка або зірочка) це спеціальний символ , який (зазвичай) інтерпретатором , перш ніж він отримує команду. Він (зазвичай) розширюється на всі імена файлів, крім тих, що мають провідні точки. Див Баш керівництва про зіставленні з зразком для отримання додаткової інформації.

Якщо розміщуватись у лапках, зірка не буде інтерпретуватися оболонкою і надається команді дослівно.


Приклади пояснено. Цитований:

grep "string" . -r --include "*.pl"

Тут grepви отримаєте опцію --includeз аргументом *.pl. Тобто 4 символьна рядок із *символом як першим символом. Що grepробити з цим рядком, повністю залежить grep. У цьому випадку --includeозначає лише розглядати файли, що відповідають шаблону *.pl.

AFAIK за кадром gnu grep використовує ту саму схему, що відповідає lib як gnu bash.

Не цитується:

grep "string" . -r --include *.pl

Тут оболонка спочатку розширить візерунок *.plна всі імена файлів, що закінчуються .pl. Припустимо , що є файли foo.pl, bar.plі baz.pl. Після розширення командний рядок виглядає приблизно так:

grep "string" . -r --include foo.pl bar.pl baz.pl

Тут grepви отримаєте опцію --includeз аргументом foo.pl, далі параметри bar.plі baz.pl. --include foo.plозначає лише розглядати файли, що відповідають шаблону foo.pl. Оскільки у шаблоні немає підстановочних знаків, єдиним файлом буде відповідність файлу з ім'ям foo.pl.

Параметри bar.plта baz.plзасоби grep також шукатимуть у цих файлах, але оскільки вони не відповідають шаблону, foo.plвони будуть ігноровані.


Це чудове спостереження. Я завжди задавався питанням, чому , grep -rздавалося несумісним , але не помітив , що це було тільки тоді , коли я використовував *.
j883376

6

Різниця полягає в тому, що якщо ви не цитуєте шаблон ( *.pl), він розширюється оболонкою. Наприклад, якщо ви запускаєте grepв каталог, який містить файл, який називається foo.pl, оскільки *plрозширений оболонкою, то grepнасправді бачить:

grep "string" . -r --include foo.pl

Оскільки ви говорите лише про включення, foo.plвін здійснюватиме пошук лише через один файл.

Якщо ви цитуєте свій шаблон, оболонка не розширить його і grepотримає правильну команду, а саме

 grep "string" . -r --include *pl

peoplне розшириться на *.pl.
unxnut

@unxnut хороший пункт, відповідь відредагована.
terdon
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.