Оболочка выполняет расширение glob, прежде чем она даже подумает о вызове команды. Такие программы, как grep, ничего не делают, чтобы предотвратить тряску: они не могут. Вы, как вызывающая сторона этих программ, должны сказать оболочке, что вы хотите передать программе специальные символы, такие как *
и ?
, и не позволять оболочке интерпретировать их. Вы делаете это, помещая их в кавычки:
grep -E 'ba(na)* split' *.txt
(ищите ba split
, bana split
и т. Д. Во всех файлах с именем .txt
). В этом случае одинарные или двойные кавычки будут работать. Между одинарными кавычками оболочка ничего не расширяет. Между двойными кавычками по-прежнему интерпретируются $
, `
и \
. Вы также можете защитить один символ от расширения оболочки, поставив перед ним обратную косую черту. Это не только символы подстановки, которые должны быть защищены; например, выше, пробел в шаблоне указан в кавычках, поэтому он является частью аргумента grep
, а не разделителем аргументов. Альтернативные способы написания приведенного выше фрагмента включают
grep -E "ba(na)* split" *.txt
grep -E ba\(na\)\*\ split *.txt
В большинстве оболочек, если аргумент содержит символы подстановки, но шаблон не соответствует ни одному файлу, шаблон остается неизменным и передается базовой команде. Так что команда вроде
grep b[an]*a *.txt
имеет различный эффект в зависимости от того, какие файлы присутствуют в системе. Если в текущем каталоге нет файлов, имя которых начинается с b
, команда ищет шаблон b[an]*a
в файлах, имя которых соответствует *.txt
. Если текущий каталог содержит файлы с именами baclava
, bnm
и hello.txt
, команда расширяется до grep baclava bnm hello.txt
, поэтому она ищет шаблон baclava
в двух файлах bnm
и hello.txt
. Само собой разумеется, это плохая идея полагаться на это в сценариях; в командной строке иногда можно сохранить набор текста, но это рискованно.
Когда вы запускаете ack .*
в каталоге, в котором нет файла точек, оболочка запускает ack . ..
. Поведение команды ack
заключается в печати всех непустых строк (шаблон .
: соответствует любому одному символу) во всех файлах под ..
(родительский элемент текущего каталога) рекурсивно. Сравните с ack '.*'
, который ищет шаблон .*
(который совпадает с любым) в текущем каталоге и его подкаталогах (из-за поведения ack
, когда вы не передаете аргумент имени файла).