лс | греп | rm - Як відформатувати цю команду?


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
Ole Tange

Відповіді:


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 єдиним забороненим символом є "null" або нульовий байт - тож це те, що вам слід використовувати в таких випадках.

У прикладі 2 вище, -print0вказує findна окремі імена файлів з нульовим байтом; те ж саме для xargs -0. (Кілька інших інструментів також мають подібні параметри, такі як sort -zабо grep -zZ.)

"Коротка версія" використовує просту підстановку оболонки ("візерунок" в bashпосібнику - див. Розділ "Розширення імені Pathname").


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

Не дуже знайомий з цим синтаксисом, але на основі оновлень я спробував це, і що ви знаєте ... це спрацювало! Спасибі!
Джефф

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