Видаліть у каталозі всі, крім 1000 випадкових файлів


13

Я дозволяю скрипту генерації даних працювати занадто довго, тепер у мене є 200 000+ файлів, які мені потрібно знизити до приблизно 1000. З командного рядка Linux, чи є простий спосіб видалити всі, крім 1000 цих файлів, де збереглися файли не матиме залежності від імені файлу чи будь-якого іншого атрибута?


Чи має процес, який створив файли, характеристику, яка стосувалась кожного файлу до попереднього? Якщо так, то важливим є вибір репрезентативного вибірки. Якщо в процесі генеруються файли, які є випадковими за своєю природою, ви можете просто видалити все після першого 1000.
fixer1234

Відповіді:


15

Видаліть у каталозі всі, крім 1000 випадкових файлів

Код:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

Пояснення:

  1. Список усіх файлів, в /path/to/dirяких є find;
    • print0: використовувати \0( нульовий символ ) як роздільник рядка; тому шляхи до файлів, що містять пробіли / нові рядки, не порушують сценарій
  2. Перемішайте список файлів sort;
    • -z: використовувати \0(нульовий символ) як роздільник, а не \n(новий рядок)
    • -R: випадковий порядок
  3. Спершу скресліть перші 1000 рядків із рандомізованого списку tail;
    • -z: трактувати список як обмежений нулем (те саме, що і з sort)
    • -n +1001: показати рядки, починаючи з 1001 (тобто опустіть перші 1000 рядків)
  4. xargs -0 rm - видаліть залишилися файли;
    • -0: з нульовим обмеженням, знову ж таки

Чому це краще, ніж рішення кіхоти *:

  1. Працює з назви файлів, що містять пробіли / нові рядки.
  2. Не намагається створити жодних каталогів (які вже можуть існувати, btw.)
  3. Не переміщує жодних файлів, навіть не торкається 1000 "файлів щасливців", крім того, щоб перерахувати їх find.
  4. Уникайте пропуску файлу у випадку, якщо вихід з якоїсь причини findне закінчується \n(новий рядок).

* - кредит на кіхот для | sort -R | head -1000, дав мені вихідну точку.


Працюючи на CentOS 6, я отримував помилки щодо недійсних операндів. На щастя, я не переймаюся пробілами у файлових маршрутах, тому видалення цих операндів працювало на менеfind . -type f | sort -R | tail -n +1001 | xargs rm
brad

@brad Чи можете ви надати повідомлення про помилки та вашу версію find? Я спробую покращити свою відповідь, просто потрібен певний внесок для роботи.
rld.

3
tail: invalid option -- 'z'версія хвоста у мене - 8.4
брад

Я б додав --no-run-if-empty до xargs, щоб уникнути помилки, якщо немає файлу (після запуску його двічі для
зразка

1

Скористайтеся тимчасовим каталогом, а потім findусі ваші файли, рандомізуйте список sortта перемістіть першу частину списку у тимчасовий каталог. Видаліть решту, а потім перемістіть файли назад із тимчасового каталогу.

$ 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«s -print0аргумент, -zаргументи sortі head, і -0з , xargsщоб забезпечити належну обробку імен файлів.

Нарешті, якщо це tmp-dirвже існує, слід замінити ім’я каталогу, яке не існує.


Це не вдасться, якщо будь-яка з перелічених імен файлів findмістить пробіл.
rld.

0

Для користувачів Mac використовується наступний сценарій.

find . -type f -print0 | tr '\0' '\n' | sort -R | tail -n +10000 | tr '\n' '\0' | xargs -0 rm

trдозволить сортування та хвіст працювати над списками \nзамість \0.


-2

Найпростіше може бути rm -rf каталог, а потім повторно запустити сценарій генерації даних, переконуючись, що він не працює занадто довго.


Це не те, що запитувала ОП. Можливо, це зробити неможливо.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.