bash на mac, установленный brew
λ brew list | grep bash
bash
λ which bash
/usr/local/bin/bash
λ rm !("shorturl.api")
-bash: !: event not found
λ ls -1 | grep -v shorturl.api | xargs rm
rm: cannot remove ''$'\033''[0m'$'\033''[01;32mapi'$'\033''[0m': No such file or directory
rm: cannot remove ''$'\033''[01;34metc'$'\033''[0m': No such file or directory
rm: cannot remove ''$'\033''[01;34minternal'$'\033''[0m': No such file or directory
rm: cannot remove ''$'\033''[00mshorturl.go'$'\033''[0m': No such file or directory
Ваши имена файлов выглядят так, как будто они содержат escape-последовательности цветов, потому что вы проанализировали вывод ls
, который представляет собой "плохая идея"ТМ.
Шаблон отрицательного подстановочного знака требует расширенного синтаксиса подстановки (shopt extglob
); см. «Как я могу использовать обратные или отрицательные подстановочные знаки при сопоставлении с образцом в оболочке unix/linux?» В версии ls
вы, по-видимому, установили ls
для вывода в цвете, поэтому последовательности перехода цвета все портят; см. «Дополнительные escape-символы из команды ls
усложняют жизнь». Это одна из многих вещей, которые могут пойти не так при синтаксическом анализе вывода ls
, поэтому не делай этого.
@MarkSetchell моя оболочка для входа в систему — это bash, echo $SHELL — это /usr/local/bin/bash.
спасибо @GordonDavisson, теперь я знаю, откуда эти escape-символы и как их отключить
Шаблон подстановки !(pattern-list)
работает только при включенном расширенном подстановке. См. раздел extglob в глобус — Greg's Wiki. В этом случае вам необходимо:
shopt -s extglob
rm -- !(shorturl.api)
--
с rm
для предотвращения того, чтобы файлы, имена которых начинаются с -
, рассматривались как параметры.Один из способов сделать это без расширенного подстановки:
find . -maxdepth 1 -type f ! -name shorturl.api -delete
Попытка ls -1 | grep -v shorturl.api | xargs rm
в вопросе нарушается несколькими способами, в том числе:
ls
предназначен для чтения людьми. Он не подходит для автоматической обработки. См. Почему вам не следует анализировать вывод ls(1).grep -v shorturl.api
исключит файлы, кроме предполагаемого. Например, old-shorturl.api
будет исключен.xargs
по умолчанию использует пробелы и новые строки, чтобы разделить ввод на аргументы. xargs rm
не будет удалять файлы, в именах которых есть такие символы.как жаль, что вывод ls не подходит для обработки xargs
@dfang, согласен. См. Есть ли причина, по которой ls не имеет опции --zero или -0 для получения дополнительной информации. find
в любом случае намного лучше для перечисления и фильтрации, но правильно отсортировать вывод find
по времени, размеру и т. д. сложно.
спасибо @GordonDavisson.
используйте ls --color перед конвейером в xargs
ls -1 --color=never | grep -v shorturl.api | xargs rm -rf
Это нарушается несколькими способами. См. мой ответ для некоторых из них.
с --color=never, это работает на моем ноутбуке :)
а с shopt -s extglob
в ` ~/.bash_profile,
rm -- !("1.txt")` проще, спасибо
Просто потому, что он запустится
/usr/local/bin/bash
, если вы наберетеbash
, это не значит, что вы сейчас используете/usr/local/bin/bash
. Оболочка, которую вы запускаете, могла быть запущена при запуске чего-то другого, кромеbash
.