如何将随机文件复制到特定文件夹?

mej*_*ius 3 command-line copy

我在几个文件夹和子文件夹中收集了大量文件(650 万),我想将一些随机选择(大约 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
.
.
.
Run Code Online (Sandbox Code Playgroud)

des*_*ert 5

通常这将是一个oneliner,但直接处理如此大量的文件(名称)可能是一个坏主意,所以我将在这里使用一个临时文件。

#!/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
Run Code Online (Sandbox Code Playgroud)

这将找到位于 中的每个文件/path/to/dir,将它们混洗并在 tempfile 中保存输出的随机行数(根据要求在 200,000 到 300,000 之间)$a。然后while循环只是将列表中的每个文件复制到/path/to/out/dir.


废话,我们根本不需要临时文件,我们只需将它传送到while循环或 - 我更喜欢 - 到trxargs

#!/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
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您甚至cp可以通过xargs'-n选项指定每次调用应该接收多少个文件名。