ls | grep | rm — Как отформатировать эту команду?

ls | grep | rm — Как отформатировать эту команду?

Я пытаюсь удалить группу файлов в определенном каталоге (в 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руководство– см. раздел «Расширение пути»).

Связанный контент