我在 AzureVM/Ubuntu 上有类似下面的存储
-/A
-/B --> 10000 log files
-/C --> 100000 log files
-/D --> 200000 images
summary.xml
-/data --> 1000 csv files
现在,因为数据量非常大,难以计算并执行任何操作,所以我想对这些数据进行抽样以开发我的数据分析代码。
我想将一个子集复制到不同的位置,该位置每个目录和嵌套目录中都有 100 个最新文件,并且根目录中的所有文件都像这样。
-/New_Location
-/B --> 100 log files
-/C --> 100 log files
-/D --> 100 images
summary.xml
-/data --> 100 csv files
我尝试了多个基于 cp 的命令,但没有任何效果,而且执行时间太长。
有人可以帮我吗?
答案1
您通常可以将其分为三个任务,首先从目录结构开始,然后像您的情况一样,将文件限制为 100 个。最后一部分反转匹配确定其余文件的范围。
#!/bin/bash
# Example START
[[ ! -d A/ ]] && { \
mkdir -p \
A/{tmp/folder,\
{A..Z}}/{images,data} && \
printf %s\\0 \
A/{summary.xml,\
tmp/De5Loh4X.tmp,\
{A..Z}/{{1..1000}_file.log,\
images/{1..1000}_pic.{jpg,png},\
data/example.csv}} | xargs -0 touch; }
### Example END
set -o noglob
source=A
target=target
number=100
# prune="-false"
prune="-type d -path $source/tmp -prune"
match='-name *.log -o -name *.jpg -o -name *.png'
echo Create directory structure.
find "$source" \
\( $prune -o -type d -links 2 \) -printf %P\\0 | cpio -0 -pvdm -D "$source" "$target"
echo Copy 100 files.
while IFS= read -rd ''; do
find "$REPLY" \
-maxdepth 1 -type f \( $match \) -printf '%T@\t%P\0' | sort -zk1rn | cut -zf2- | head -zn $number | cpio -0 -pvdm -D "$REPLY" "$target/${REPLY/#$source\//}"
done < <( \
find "$source" \
\( $prune -false -o -type f \) -printf %h\\0 | sort -zu \
)
echo Copy everything else.
find "$source" \
\( $prune -false -o -type f ! \( $match \) \) -printf %P\\0 | cpio -0 -pvdm -D "$source" "$target"
答案2
这可以通过选择性归档轻松完成。您可以将文件打包(仅打包目标文件),然后将打包文件解压到其他地方。我假设您的日志文件除了编号外具有相同的名称(例如 log1、log2 等)。因此,可以在 tarball 命令中将前 100 个文件定义为 log{1..100}。例如:
tar -cvf copied.tar <path1>/log{1..100} <path2>/log({1..100}
ETC
当你解压时,原始文件结构将在新位置重新创建。因此,你可能需要使用“--strip-components=”选项来截断多余的前导目录以避免混乱。