Я пытаюсь удалить группу файлов в определенном каталоге (в Mac OS X с помощью Терминала)
ls | grep \([1-9]\) | xargs rm
Должно сработать, но не срабатывает. Я пытаюсь удалить любой файл с одной цифрой в скобках в имени файла (дубликаты, загруженные из сети), но в итоге получается что-то вроде этого:
> rm: 520syllabus2010: No such file or
> directory rm: (3).pdf: No such file or
> directory
потому что он не интерпретирует пространство правильно. Он должен удалить "520syllabus2010 (3).pdf"
Как правильно это сделать?
Спасибо, Джефф.
решение1
Укороченная версия:
rm *\([1-9]\)*
Не передавайте данные ls
на xargs
. Вместо этого передавайте данные find ... -print0
на xargs -0
, чтобы избежать подобных проблем.
find . -maxdepth 1 -name '*([1-9])*' -print0 | xargs -0 rm
...что можно записать как:
find . -maxdepth 1 -name '*([1-9])*' -exec rm {} \;
и:
find . -maxdepth 1 -name '*([1-9])*' -delete
который можно сократить до простого rm
подстановочного знака.
Обычно ls
и find
разделяет имена файлов символами новой строки, но xargs
разделяет входные данные символом новой строкиилипространство, что приводит к поведению, которое вы видите.
Можно сказать, что можно xargs
разделить только по новой строке, но файлыможеттакже имеют в своих именах символы новой строки. Фактически, в Linux и BSD,только запрещенный символэто"нулевой"или нулевой байт– так вот именно его и следует использовать в таких случаях.
В примере 2 выше -print0
указывается , find
что имена файлов следует разделять нулевым байтом; то же самое для xargs -0
. (Некоторые другие инструменты также имеют похожие параметры, такие как sort -z
или grep -zZ
.)
«Короткая версия» использует простой подстановочный знак оболочки («шаблон» вbash
руководство– см. раздел «Расширение пути»).