Я пытаюсь удалить набор файлов в определенном каталоге (на 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"
Каков надлежащий способ сделать это?
Спасибо, Jeff
Короткая версия:
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
руководство – видит раздел "Pathname Expansion").