У меня есть следующие файлы:
$ ls *.png | egrep -i "am|pm"
output-0 11.42.30 AM.png
output-0 5.10.12 PM.png
....
Я хочу удалить их, но получить эту ошибку:
$ ls *.png | egrep -i "am|pm" | while read line; do rm "$line"; done
rm: cannot remove ''$'\033''[0m'$'\033''[01;35moutput-0 11.42.30 AM.png'$'\033''[0m': No such file or directory
rm: cannot remove ''$'\033''[01;35moutput-0 5.10.12 PM.png'$'\033''[0m': No such file or directory
rm: cannot remove ''$'\033''[01;35moutput-1 11.42.30 AM.png'$'\033''[0m': No such file or directory
Какова проблема с моими кодами?
ls
опасно в сценариях и командных строках. Одна проблема - то, что описано в комментарии @PerlDuck, escape-последовательностей ANSI для вывода цвета. Я рекомендовал бы другой подход с find
Создайте тестовые файлы
touch 'output-0 11.42.30 AM.png' 'output-0 5.10.12 PM.png' asdf.png
Проверьте что find
командная строка находит файлы, которые Вы ожидаете, что это найдет
find . -type f -iname "*[ap]m*.png"
и сделайте это
find . -type f -iname "*[ap]m*.png" -delete
Если Вы не хотите искать в подкаталоги, добавить -maxdepth 1
find . -maxdepth 1 -type f -iname "*[ap]m*.png" -delete
Проверьте результат
ls
Файлами с является, пополудни, AM, PM на имя должен быть удален, но asdf.png
не удален.
Если Вы действительно хотите использовать a while read
цикл таким образом, затем используйте шарик оболочки и printf
с пустыми разделителями, например.
printf '%s\0' *.png | grep -zEi 'am|pm' | while IFS= read -r -d '' line; do echo "$line"; done
Однако существует несколько способов добраться bash
расшириться до списка файлов, которые будут удалены непосредственно - без потребности передать по каналу к grep
и while
:
использование простых шариков оболочки
rm -- *[ap]m.png *[AP]M.png
или - если Вы не возражаете соответствовать a .PNG
расширение также - использование nocaseglob
опция
shopt -s nocaseglob
rm -- *[ap]m.png
использование расширенных шариков
shopt -s extglob
rm -- *@(AM|PM).png *@(am|pm).png
или
shopt -s extglob nocaseglob
rm -- *@(am|pm).png
--
отмечает конец опций, на всякий случай существуют имена файлов, которые начинаются с дефиса - можно использовать шаблон с явным префиксом каталога как ./*(am|pm)
вместо этого, если Вы предпочитаете.
Добавьте -i
или -I
опция, если Вы хотите рассмотреть имена файлов в интерактивном режиме перед удалением.