Как скопировать случайные файлы в определенную папку?

У меня есть огромная коллекция файлов (6,5 миллионов) в нескольких папках и подпапках, и я хочу скопировать некоторые случайные выборки (около 200k-300k файлов) в каталог, чтобы сделать рандомизированный образец.

это дерево папок (это всего лишь небольшая выборка) внутри каждой папки есть несколько файлов

. ├── articles.0-9A-B.txt │   ├── 20_Century_Br_Hist │   ├── 3_Biotech │   ├── A_A_Case_Rep │   ├── AAPS_J │   ├── AAPS_PharmSciTech │   ├── Abdom_Imaging │   ├── Abdom_Radiol │   ├── Abdom_Radiol_(NY) │   ├── Acad_Emerg_Med │   ├── Acad_Med │   ├── Acad_Psychiatry │   ├── Acad_Radiol │   ├── Acc_Chem_Res . . . │   ├── Bull_Sci_Technol_Soc │   ├── Bull_Volcanol │   ├── Bull_World_Health_Organ │   ├── Bundesgesundheitsblatt_Gesundheitsforschung_Gesundheitsschutz │   ├── Burn_Res │   ├── Burns │   ├── Burns_Trauma │   └── Bus_Soc ├── articles.A-B.xml │   ├── 20_Century_Br_Hist │   ├── 3_Biotech │   ├── A_A_Case_Rep │   ├── AAPS_J │   ├── AAPS_PharmSciTech │   ├── Abdom_Imaging . . .
3
задан 17 November 2017 в 15:58

3 ответа

Обычно это будет oneliner, но может быть плохой идеей обрабатывать такое огромное количество файлов (имя) s напрямую, поэтому я буду использовать временный файл здесь.

#!/bin/bash
a=$(mktemp)
find /path/to/dir -type f | shuf -n $(shuf -i200000-300000 -n1) >$a
while IFS='' read -r l || [[ -n "$l" ]]; do
    cp "$l" /path/to/out/dir
done <$a

Это найдет каждый файл, расположенный в /path/to/dir, перетасуйте их и сохраните случайное количество строк (от 200 000 до 300 000, как было запрошено) на выходе в tempfile $a. Затем цикл while просто копирует все файлы в списке в /path/to/out/dir.

Глупость, нам вообще не нужен файл tempfile, мы просто подключаем его к while или - что я предпочитаю - tr и xargs:

#!/bin/bash
find /path/to/dir -type f | shuf -n $(shuf -i200000-300000 -n1) |\
tr '\n' '\0' | xargs -0 -n1 cp -t /path/to/out/dir

Таким образом, вы даже можете указать, сколько имен файлов каждый вызов cp должен получать через xargs ] '-n.

4
ответ дан 22 May 2018 в 16:09

Обычно это будет oneliner, но может быть плохой идеей обрабатывать такое огромное количество файлов (имя) s напрямую, поэтому я буду использовать временный файл здесь.

#!/bin/bash a=$(mktemp) find /path/to/dir -type f | shuf -n $(shuf -i200000-300000 -n1) >$a while IFS='' read -r l || [[ -n "$l" ]]; do cp "$l" /path/to/out/dir done <$a

Это найдет каждый файл, расположенный в /path/to/dir, перетасуйте их и сохраните случайное количество строк (от 200 000 до 300 000, как было запрошено) на выходе в tempfile $a. Затем цикл while просто копирует все файлы в списке в /path/to/out/dir.

Глупость, нам вообще не нужен файл tempfile, мы просто подключаем его к while или - что я предпочитаю - tr и xargs:

#!/bin/bash find /path/to/dir -type f | shuf -n $(shuf -i200000-300000 -n1) |\ tr '\n' '\0' | xargs -0 -n1 cp -t /path/to/out/dir

Таким образом, вы даже можете указать, сколько имен файлов каждый вызов cp должен получать через xargs ] '-n.

4
ответ дан 18 July 2018 в 03:07

Обычно это будет oneliner, но может быть плохой идеей обрабатывать такое огромное количество файлов (имя) s напрямую, поэтому я буду использовать временный файл здесь.

#!/bin/bash a=$(mktemp) find /path/to/dir -type f | shuf -n $(shuf -i200000-300000 -n1) >$a while IFS='' read -r l || [[ -n "$l" ]]; do cp "$l" /path/to/out/dir done <$a

Это найдет каждый файл, расположенный в /path/to/dir, перетасуйте их и сохраните случайное количество строк (от 200 000 до 300 000, как было запрошено) на выходе в tempfile $a. Затем цикл while просто копирует все файлы в списке в /path/to/out/dir.

Глупость, нам вообще не нужен файл tempfile, мы просто подключаем его к while или - что я предпочитаю - tr и xargs:

#!/bin/bash find /path/to/dir -type f | shuf -n $(shuf -i200000-300000 -n1) |\ tr '\n' '\0' | xargs -0 -n1 cp -t /path/to/out/dir

Таким образом, вы даже можете указать, сколько имен файлов каждый вызов cp должен получать через xargs ] '-n.

4
ответ дан 24 July 2018 в 17:45

Другие вопросы по тегам:

Похожие вопросы: