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


11

Я пытаюсь удалить кучу файлов в определенном каталоге (в 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
Ваш пример имени файла не содержит литерал #.
Бенджамин Банье

1
@honk: он не ищет буквального #.
Игнасио Васкес-Абрамс

1
Из-за расширения оболочкой, это не будет работать должным образом, если cwd имеет файл с именем например (3). Лучше процитировать аргументы, чтобы оболочка не влияла на них.
Игнасио Васкес-Абрамс

1
Вы столкнулись с проблемой разделителя en.wikipedia.org/wiki/Xargs#The_separator_problem
Оле Танге

Ответы:


19

Укороченная версия:

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руководстве - см. Раздел «Расширение пути»).


1
И просто, чтобы быть в безопасности, лучше использовать *" "\\([1-9]\\).*так, чтобы удалялись только файлы с пробелом перед номером паренса перед (a, если честно) периодом.
Игнасио Васкес-Абрамс

Не очень знакомый с этим синтаксисом, но на основании положительных отзывов я попробовал и что вы знаете ... это сработало! Благодарность!
Джефф

1
+1. -print0 необходим для правильной передачи в xargs.
Крис В. Ри
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.