Я ожидал, что:
$ rm *(1)*
удалил бы все файлы, содержащиеся (1)
в имени. Я ошибался. Он удалил все файлы в каталоге.
Почему?
Я ожидал, что:
$ rm *(1)*
удалил бы все файлы, содержащиеся (1)
в имени. Я ошибался. Он удалил все файлы в каталоге.
Почему?
Ответы:
От man bash
:
*(pattern-list)
Matches zero or more occurrences of the given patterns
У вас есть выражение glob, которое соответствует файлам, начинающимся с нуля или более 1
s - это все файлы.
Один простой способ отключить это глобальное поведение - \
избежать скобок:
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:
).