Рекурсивно удалять файлы с idx> 10000

Проблема

В текущем рабочем каталоге у меня несколько (очень много) папок, и у некоторых из них есть много (например, 100 000+) файлов внутри.

Моя цель – получить только папку с 10 000 + файлами и удалить folderName10001.ext и выше (где folderName – это фактическое имя содержащейся папки, а extлюбое расширение).

Подход

Я пытаюсь напечатать nameFolder numberOfFiles с bash .

 find . -maxdepth 1 -type d -name 'acer' -exec sh -c "echo {}; ls {} | wc -l" \; 

Это работает просто отлично (для образца папки acer ), но выход

 ./acer 6058 

Я хотел бы иметь 1-строчный вывод для каждой папки

 find . -maxdepth 1 -type d -name 'acer' -exec sh -c "echo {} `ls {} | wc -l`" \; 

говорит ls: cannot access {}: No such file or directory .


Вопросов

  1. Как я могу отобразить в одной строке nameFolder numberOfFiles ?
  2. Есть ли более простой способ удалить каждую папку folderName/folderName#.ext , с # > 10000 ?

вопрос 2

Некоторые подробности могут помочь понять, что происходит.

У меня есть папка со следующим деревом

 . ├── a │  ├── a1.ext │  ├── a2.ext │  ├── a3.ext │  └── a4.ext ├── b │  ├── b1.ext │  ├── b2.ext │  ├── b3.ext │  └── b4.ext └── c ├── c1.ext ├── c2.ext ├── c3.ext └── c4.ext 

Я хотел бы удалить каждый файл с номером больше 2 . (В моем конкретном случае порог установлен в 10000 )


Ответ 1

Это все о том, кто интерпретирует то, что (спасибо @Bratchley за советы в комментариях).

Поскольку я печатаю в bash , bash сначала интерпретирует то, что я набираю. Если я хочу, чтобы bash послал, чтобы find bash backtick , тогда мне нужно его избежать .

 find . -maxdepth 1 -type d -name 'acer' -exec sh -c "echo {} \`ls {} | wc -l;\`" \; 

который дает мне

 ./acer 6058 

@Barmar указывает, что одиночные и двойные кавычки ведут себя по-разному , и поэтому

 find . -maxdepth 1 -type d -name 'acer' -exec sh -c 'echo {} `ls {} | wc -l`' \; 

будет отлично работать (примечание " заменено на ' ).

Ответ 2

Это было сделано Уолтером А , и это принятый ответ на этот вопрос.

Больше ошибок (приведено несколько примеров) …

 black: 390120 ./clean.sh: line 6: /bin/ls: Argument list too long rm: missing operand Try 'rm --help' for more information. leather: 118240 ./clean.sh: line 6: /bin/ls: Argument list too long rm: missing operand Try 'rm --help' for more information. 

Хорошо, я исправил его с помощью

 ls -d */ | cut -d/ -f1 | while read dir; do COUNT=$(ls $dir | wc -l); if [ ${COUNT} -gt 10000 ]; then echo "$dir: ${COUNT}" ; for i in `seq 10001 ${COUNT}`; do rm ${dir}/${dir}${i}.* done fi done 

2 Solutions collect form web for “Рекурсивно удалять файлы с idx> 10000”

Вы могли бы написать

 ls -d */ | while read dir; do echo "$dir: $(ls $dir | wc -l)" done 

Когда имена файлов нумеруются без начальных нулей, вы можете попробовать

 ls -d */ | cut -d/ -f1 | while read dir; do COUNT=$(ls $dir | wc -l); echo "$dir: ${COUNT}" ; if [ ${COUNT} -gt 10000 ]; then ls ${dir}/${dir}?????*.ext | grep -v ${dir}/${dir}10000.ext | xargs rm fi done 

Другой подход был бы возможен, если у вас есть ведущие нули в именах файлов:

 ls -d */ | cut -d/ -f1 | while read dir; do ls ${dir}/${dir}*.ext | tail -n +10001 | xargs rm done 

Изменить: Включено dir + имя файла в командах ls, и я добавил cut -d/ -f1 | отрезать конечную /.

Используйте одинарные кавычки вместо двойных кавычек, так что обратные ссылки и $ не интерпретируются исходной оболочкой:

 find . -maxdepth 1 -type d -name 'acer' -exec sh -c 'echo {} $(ls {} | wc -l)' \; 

Во втором вопросе я бы поставил то, что вы хотите сделать, в отдельный скрипт, который принимает имя каталога в качестве аргумента. Затем выполните:

 find . -maxdepth 1 -type d -name 'acer' -exec ./scriptname {} \; 

Таким образом вам не нужно иметь дело со всеми вопросами, связанными с использованием -exec sh -c .

  • Содержимое файла / proc / <PID> / cmdline зависит от скрипта shebang?
  • Значение следующих команд Linux
  • Ввод папки с пробелами и escape-символами с использованием bash
  • Установите переменные переменных переменных в bash (или другие)
  • mutt не запускается как задание cron, завернутое в сценарий bash
  • Перепишите аргументы перед передачей их команде
  • Извлечь только часть версии пакета с именем bash
  • Как сопоставить и заменить значение атрибута внутри тега
  • Как установить сценарий, который он будет запускать при запуске во FreeBSD?
  • Баш обнаруживает искусство ascii
  • Запустите сценарий оболочки и прочитайте вывод в переменной и запустите другой скрипт на основе вывода
  • Каков стандарт для отступов в сценариях оболочки?
  • Interesting Posts

    Как установить шрифт виртуальной консоли на Arch?

    Какой дистрибутив Linux лучше всего использовать в качестве медиа-сервера для удаленного хранения и доступа к фильмам и музыке в сети

    Каков список кэшей разных типов в файловых системах Linux?

    Что включать в RPM, созданный из пакетов python

    FreeBSD 10 на VirtualBox не загружается в GDM

    Начать KDE 5 Plasma с nouveau.noaccel = 1 (без 3D-ускорения)

    Случайно установленное разрешение экрана слишком велико, оно не изменится назад

    Завершение zsh: получение имен файлов из определенного каталога

    Присвоение переменных

    Вывод NamingVariable для нескольких файлов в сценарии Bash

    Тестирование HDD En Masse

    Как сделать восстановление данных очень-очень сложно или невозможно для Unix-компьютера перед перепродажей?

    Использовать файлы math.h и ссылок объектов без -lm

    2 последовательных входа в систему ssh

    Vim: скопируйте, затем вставьте несколько раз

    Linux и Unix - лучшая ОС в мире.