Есть ли элегантный и быстрый способ скопировать определенную структуру каталогов и выбрать только случайное количество файлов для копирования с ней. Например, у вас есть структура:
--MainDir
--SubDir1
--SubSubDir1
--file1
--file2
--...
--fileN
--...
--SubSubDirN
--file1
--file2
--...
--fileN
--...
Я хочу скопировать всю структуру папок, но выбрать только определенное количество случайных файлов из {files1-filesN} каждого SubSubDir для копирования.
решение1
Поскольку вы отметили это как, linux
я предполагаю, что это утилиты GNU.
Скопировать структуру каталогов из $src
в $dest
:
find "$src" -type d -print0 | cpio -padmv0 "$dest"
Также скопируйте случайную выборку $nfile
файлов из каждого конечного подкаталога $src
:
find "$src" -type d -links 2 -exec \
sh -c 'find "$1" -type f -print0 | shuf -z -n "$2"' sh {} "$nfiles" \; | \
cpio -padmv0 "$dest"
Здесь первый find
находит конечные подкаталоги ( -links 2
), затем второй find
находит файлы в каждом из этих подкаталогов, shuf
выбирает случайную выборку файлов и, наконец, cpio
копирует их.
решение2
Сначала найдите все каталоги:
find MainDir -type d
Затем проанализируйте эти каталоги в скрипте
find MainDir -type d -exec ./randomCopy.sh 2 {} \;
, который
- Создает целевой каталог
- Копирует случайное количество файлов.
В этом случае копируются 2 случайных файла.
В моем примере скрипт randomCopy.sh
выглядит так:
#!/bin/bash
cnt="$1"
dir="$2"
mkdir -p "TARGET/$dir"
# see: https://stackoverflow.com/questions/414164/how-can-i-select-random-files-from-a-directory-in-bash
find "$dir" -maxdepth 1 -type f | sort -R | tail -n $cnt | while read file; do
# copy the file
cp "$file" "TARGET/$dir/"
done
И не забудьте сделать скрипт исполняемым: chmod +x randomCopy.sh
.
Замените строку TARGET
на целевой каталог или используйте третий параметр скрипта.
Это доказательство концепции запущено в моем тестовом каталоге, но, возможно, многое еще предстоит улучшить.