Почему rm не удаляет файлы, переданные из find или sed?

Я хочу передать следующие команды конвейером, но последний cmd «rm -rf» не работает, т.е. ничего не удалено:

find /home/mba/Desktop/ -type d -name "logs" | sed 's/$/\/\*/' | rm -rf

Ошибка не возвращается.


person Muhammad Badawy    schedule 19.07.2014    source источник
comment
@CodeGnome: для получения дополнительной информации см. Его сообщение: stackoverflow.com/q/24841899/3776858   -  person Cyrus    schedule 19.07.2014


Ответы (3)


Команда rm не берет имена файлов из стандартного ввода. Если вы хотите перенаправить с sed на rm, вы можете использовать xargs. Например:

find /home/mba/Desktop/ -type d -name "logs" | sed 's/$/\/\*/' | xargs rm -rf
person Todd A. Jacobs    schedule 19.07.2014
comment
Команда sed не нужна. Команда find распечатает список путей к каталогам с последним компонентом каждого пути, являющимся журналами. Команда rm с параметром -r затем рекурсивно удалит каталог. - person Nick; 10.08.2014

Более простая форма:

find /home/mba/Desktop/ -regex '.*/logs/[^/]+$' -exec rm -fr -- {} +

Он будет соответствовать всем файлам, находящимся в любом каталоге с именем logs.

Если xargs по-прежнему предпочтительнее:

find /home/mba/Desktop/ -regex '.*/logs/[^/]+$' -print0 | xargs -0 rm -fr --

Вы можете ограничить количество файлов, удаляемых за один раз, с помощью -n:

find /home/mba/Desktop/ -regex '.*/logs/[^/]+$' -print0 | xargs -0 -n 2000 rm -fr --
  • Мы используем -print0 и -0, чтобы использовать \x00 в качестве разделителя. Это обеспечит безопасность команды с именами файлов, содержащими пробелы.
  • Мы также добавляем -- к rm, чтобы мы могли удалять файлы, имена которых начинаются с -.
person konsolebox    schedule 19.07.2014
comment
@chepner Вы, наверное, имеете в виду -wholename. Но это также будет соответствовать файлам выше 1 уровня и вызовет ошибку позже, что файл не был найден полностью, потому что родительский элемент был удален перед ним. Или, может быть, rm -fr все равно проигнорирует это, но это все еще неэффективно. - person konsolebox; 19.07.2014
comment
Нет никакой пользы от ограничения количества аргументов до rm; xargs будет производить команды, которые имеют столько аргументов, сколько может поддерживать операционная система (до 131072 байта, хотя это может варьироваться). Такое ограничение числа только заставит больше вызовов команды и замедлит все это. Причина, по которой вы хотите использовать xargs, а не аргумент -exec для поиска, заключается в том, что вы хотите уменьшить количество раз, которое вам нужно выполнить команду - person Nick; 10.08.2014
comment
@Nick Это поведение по умолчанию даже в старых версиях xargs? И есть ли документ, в котором это упоминается? - person konsolebox; 10.08.2014
comment
Привет. Справочная страница для xargs хороша (немного длинная, если вы торопитесь). Поведение Xargs, как я его описал, не изменилось за много лет. Максимальное значение командной строки со временем изменится. - person Nick; 10.08.2014

«Стандартный ввод должен использоваться для чтения строки ввода в ответ на каждое приглашение, указанное в разделе STDOUT. В противном случае стандартный ввод не должен использоваться».

Источник: http://pubs.opengroup.org/onlinepubs/007904975/utilities/rm.html

Примеры:

yes n | rm -ir dir1 dir2 dir3      # won't delete dir1 dir2 dir3

yes y | rm -ir dir1 dir2 dir3      # delete dir1 dir2 dir3
person Cyrus    schedule 19.07.2014