Рекурсивно удалять файлы с 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 

  • Заменить сценарии развертывания с помощью незамысловатого
  • Fdisk в интерактивном режиме
  • Простая, если команда не работает в скрипте csh
  • Локальные переменные в zsh: что эквивалентно «export -n» bash в zsh
  • Как использовать команду tee с эхом в соответствии с требованиями ниже?
  • Асинхронный RPROMPT?
  • «Список аргументов слишком длинный» для цикла
  • Как использовать одинарные кавычки внутри ssh и sqlplus
  • 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 .

    Interesting Posts

    Grub не распознает пароль

    Обновление списка шрифтов

    Не совпадать ни с регулярным выражением

    Как заставить «экран» очистить терминал после команд типа `htop`

    Докер с аудио в режиме реального времени / с низкой задержкой? (для виртуальных усилителей, таких как Guitarix …)

    Кросс-компиляция базы Linux для системы Big-Endian

    Как отключить TCP / IP для адаптера Ethernet?

    Резервное копирование базы данных svn и базы данных mysql на ежедневной основе

    Найти и заменить с помощью частей найденной строки в строке замены

    Как проверить цель символической ссылки указывает на конкретный путь

    Как распечатать переменную с выравниванием по центру?

    Значок / настройки громкости, не отображаемые в «системном трее», до этого просто исчезли

    bluez: наушники bluetooth не могут повторно подключаться после отключения

    Построить сумо 0.17.1 на Ubuntu 10.10

    Как настроить AMD Cayman / Antilles HDMI Audio (Radeon HD 6900 series)?

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