Я ожидал, что:
$ rm *(1)*
удалил бы все файлы, содержащиеся (1)в имени. Я ошибался. Он удалил все файлы в каталоге.
Почему?
Я ожидал, что:
$ rm *(1)*
удалил бы все файлы, содержащиеся (1)в имени. Я ошибался. Он удалил все файлы в каталоге.
Почему?
Ответы:
От man bash:
*(pattern-list)
Matches zero or more occurrences of the given patterns
У вас есть выражение glob, которое соответствует файлам, начинающимся с нуля или более 1s - это все файлы.
Один простой способ отключить это глобальное поведение - \избежать скобок:
rm *\(1\)*
В противном случае вы можете использовать, shopt -u extglobчтобы отключить поведение и shopt -s extglobснова включить его:
shopt -u extglob
rm *(1)*
shopt -s extglob
Обратите внимание, что, как говорит Стефан , extglobон включен, bash-completionпоэтому его отключение может привести к неправильной работе функций завершения.
extglobон не включен по умолчанию, но включен bash_completion, если он установлен и включен. bashне имеет локальной области действия для опций, как zshделает.
bash-4.3есть регрессия, которая *(1)*также расширяет скрытые файлы.
Это, вероятно, связано с extglobопцией оболочки. Если я выключу его, шаблон выдаст сообщение об ошибке:
martin@dogmeat:~$ shopt -u extglob
martin@dogmeat:~$ shopt extglob
extglob off
martin@dogmeat:~$ echo *(1)*
bash: syntax error near unexpected token `('
Если я включу его, то оно действительно будет соответствовать всему. Справочная страница документирует эти шаблоны, я думаю, что они связаны:
If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the fol‐
lowing sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
Я не вижу никакой документации, которая бы указывала, что делают круглые скобки без ведущего символа. Во всяком случае, вы можете обойти эту проблему, цитируя скобки:
martin@dogmeat ~ % echo *\(1\)*
A(1)b
Кроме того, сначала используйте echoили lsдля проверки вашего шаблона, если вы не совсем уверены, что это работает :)
{это скобка, (это пара (или круглая скобка).
{= фигурная скобка, (= круглая скобка, [= квадратная скобка. На американском языке: {= скобка, (= paren, [= скобка. Немного смущает. Если вам когда-нибудь понадобится проверить, что-то называется, Jargon File - ASCII весьма полезен.
{это цветочная скобка, [квадратная скобка и (круглая скобка или чаще просто скобка. :-)
rmс шаблоном, я всегда предшествую емуechoперед выполнением фактической команды. Привычка спасала меня не раз (с тех пор, когда мне было около 6 лет, путала разницу междуDEL A: *.*иDEL *.* A:).