arrays - 列出两个文件夹中的所有文件,然后随机遍历组合列表
问题描述
我有两个包含照片的目录,我想在每次运行脚本时对其进行操作以输出文件的随机顺序。我将如何创建这样的列表?
d1=/home/Photos/*.jpg
d2=/mnt/JillsPC/home/Photos/*.jpg
# somehow make a combined list, files = d1 + d2
# somehow randomise the file order
# during execution of the for;do;done loop, no file should be repeated
for f in $files; do
echo $f # full path to each file
done
解决方案
如果你不需要,我不会使用变量。如果将几个命令与管道或进程替换链接在一起会更自然。这样一来,一切都在数据流上运行,而无需一次将整个名称列表加载到内存中。
您可以使用shuf
随机排列输入行,并find
每行列出一个文件。或者,为了最大程度地安全,让我们使用\0
分隔符。最后,带有进程替换的 while 循环将逐行读取到变量中。
while IFS= read -d $'\0' -r file; do
echo "$file"
done < <(find /home/Photos/ /mnt/JillsPC/home/Photos/ -name '*.jpg' -print0 | shuf -z)
也就是说,如果您确实想使用一些变量,那么您应该使用数组。数组正确处理带有空格和其他特殊字符的文件名,而常规字符串变量将它们全部搞砸。
d1=(/home/Photos/*.jpg)
d2=(/mnt/JillsPC/home/Photos/*.jpg)
files=("${d1[@]}" "${d2[@]}")
按顺序迭代很容易:
for file in "${files[@]}"; do
echo "$file"
done
洗牌虽然很棘手。shuf
仍然是最好的工具,但它在数据流上效果最好。我们可以用来打印每个文件名,并带有我们需要使快乐printf
的尾随。\0
shuf -z
d1=(/home/Photos/*.jpg)
d2=(/mnt/JillsPC/home/Photos/*.jpg)
files=("${d1[@]}" "${d2[@]}")
while IFS= read -d $'\0' -r file; do
echo "$file"
done < <(printf '%s\0' "${files[@]}" | shuf -z)
进一步阅读:
推荐阅读
- c# - 如何在 ASP.NET Core 2.2 中实现标识
- hibernate - 无法理解查询缓存和 L2C 在休眠中的工作方式
- javascript - 使用 Jest 按顺序运行 Puppeteer 测试
- java - 使用骆驼拆分器拆分列表列表
- html - GIF。在页面之前加载
- javascript - 如何在 Lodash _.each 中获取数组索引
- java - 如何始终记住每个传感器的最新值并将它们写入文件?
- amazon-ec2 - HAProxy - 基于 URL /路径路由到后端 IP?
- traefik - 如何实现 Traefik 非 docker 多域转发
- sql - 访问更新查询:不更新某些行