Я позволил сценарию генерации данных работать слишком долго, теперь у меня есть более 200 000 файлов, которые мне нужно сократить до 1000. Из командной строки Linux есть простой способ удалить все эти файлы, кроме 1000, где файлы, которые будут сохранены, не будут зависеть от имени файла или любого другого атрибута?
3 ответа
Удалить все кроме 1000 случайных файлов в каталоге
Код:
find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm
Объяснение:
- Вывести список всех файлов в
/path/to/dir
с помощьюfind
;print0
: использовать\0
(нулевой символ) в качестве разделителя строк; поэтому пути к файлам, содержащие пробелы / переводы строк, не нарушают сценарий
- Перемешать список файлов с помощью
sort
;-z
: использовать\0
(нулевой символ) в качестве разделителя вместо\n
(перевод строки)-R
: случайный порядок
- Уберите первые 1000 строк из рандомизированного списка с
tail
;-z
: обрабатывать список как разделенный нулями (так же, как и сsort
)-n +1001
: показать строки, начинающиеся с 1001 (т. е. пропустить первые 1000 строк)
xargs -0 rm
- удалить оставшиеся файлы;-0
: опять с нулевым разделением
Почему это лучше, чем решение Quixotic *:
- Работает с именами файлов, содержащими пробелы / переводы строк.
- Не пытается создать какие-либо каталоги (которые могут уже существовать, кстати.)
- Не перемещает никаких файлов, даже не касается 1000 "счастливых файлов", кроме перечисления их с помощью
find
. - Позволяет избежать пропуска файла в случае, если вывод команды
find
по какой-либо причине не заканчивается на\n
(перевод строки).
* - кредит на Quixotic для | sort -R | head -1000
, дал мне отправную точку.
Используйте временный каталог, затем find
все свои файлы, перемешайте список с помощью sort
и переместите верхнюю 1000 списка во временный каталог. Удалите остальные, затем переместите файлы обратно из временного каталога.
$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .
Если xargs
жалуется на длину линии, использовать меньшее число с head
и повторить команду при необходимости (то есть изменить -1000
-500
и запустить его в два раза, или изменить -200
и запустить его в 5 раз.)
Он также не сможет обрабатывать имена файлов, которые содержат пробелы; а @ ответ RLD в шоу, вы можете использовать find
аргумент -print0
«s, то -z
аргументы для sort
и head
а также -0
с xargs
для обеспечения надлежащего обращения имени файла.
Наконец, если tmp-dir
уже существует, вы должны заменить имя каталога, которое не существует.
Самым простым может быть rm -rf каталога, а затем перезапустить сценарий генерации данных, убедившись, что он не выполняется слишком долго.