У меня есть огромная коллекция файлов (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
.
.
.
Обычно это будет 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.
Обычно это будет 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.
Обычно это будет 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.