Как удалить каталоги на основе вывода `find`: ТОЛЬКО первый результат

Как удалить каталоги на основе вывода `find`: ТОЛЬКО первый результат

Исходя из этого вопроса,

Как удалить каталоги на основе вывода `find`?

Я попытался удалить только первую папку из результата:

find * -type d | head -n1 | -exec rm -rf {} \;

Но я получаю эту ошибку:

bash: -exec: command not found

В чем дело?

решение1

Вы можете использовать -quitпосле использования -deleteили -exec:

-покидать
Выйти немедленно. Дочерние процессы не будут оставлены запущенными, но пути, указанные в командной строке, больше не будут обрабатываться.


Удаление первого результата вашей findкоманды:

find * -type d -exec rm -Rf {} \; -quit

или

find . ! -path . -type d -exec rm -Rf {} \; -quit

Последний найдет скрытые папки.


Обратите внимание, что ваш вывод может бытьне сортироваться в алфавитном порядке.

Для удаления первого результата после сортировки:

find * -maxdepth 1 -type d -print0 | sort -z | head -zn1 | xargs -r0 rm -Rf

Для числовой сортировки используйте sort -zn.

решение2

pLumo адекватно предоставил несколько хороших альтернативных решенийв их ответе. Я предлагаю совершенно другой подход.

Вы заметите, что findкоманда, используемая вами для *описания путей поиска верхнего уровня, на самом деле используется только длянаходим первый каталог среди имен, который *расширяется до.

Вы также можете сделать это с помощью цикла оболочки, что позволит легче читать код и видеть, что он делает:

shopt -s dotglob nullglob

for name in *; do
    if [ -d "$name" ] && [ ! -h "$name" ]; then
        rm -rf -- "$name"
        break
    fi
done

Этот цикл, который предполагает, что он запущен в bashоболочке, перебирает все имена, соответствующие *(включая скрытые имена). Тело цикла проверяет, является ли текущее имя каталогом (не являясь символической ссылкой на каталог), и если это так, рекурсивно удаляет каталог перед выходом из цикла.

Похожий эффект можно получить в zshоболочке с помощью гораздо более простой команды

rm -rf -- *(D/[1])

Это удаляет первый каталог, который *расширяется до. Квалификатор подстановки (D/[1])ограничивает соответствие *только каталогами ( /), но включает скрытые имена ( D) и возвращает только первое совпадающее имя ( [1]). Если в текущем каталоге нет каталогов, вы получите сообщение об ошибке «соответствий не найдено» от оболочки.

решение3

Это кажется очень опасным, но вы можете попробовать:

find * -type d | head -n1 | xargs rm -rf

решение4

для меня сработал этот код:

  • находит ТОЛЬКО файлы с -type f,
  • фильтровать файлы, не содержащие ".gz"
  • выбрать N файлов, в этом случае ТОЛЬКО ПЕРВЫЙ -n 1

код:

найти . -тип f ! -имя "*.gz" | head -n 1 | xargs rm -rf {} ;

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