【问题标题】:Randomly select a file with a given extension and copy it to a given directory随机选择具有给定扩展名的文件并将其复制到给定目录
【发布时间】:2017-08-31 15:14:11
【问题描述】:

我想编写一个简单的 bash 脚本,从 /music/ 文件夹中随机选择一个 .flac 文件(它必须是递归的,因为该文件夹中有很多子文件夹),然后将该文件复制到 @987654324 @

This post 非常接近我想要做的事情,但我不确定如何更改脚本来做我想做的事情。

我试过这个:

ls /music |sort -R |tail -1 |while read file; do
    cp $file /test/random.flac
done

但我不知道如何告诉ls 对子文件夹中的所有.flac 进行递归搜索。

【问题讨论】:

  • 到目前为止您尝试过什么?是什么导致您在检索文件或选择随机文件时遇到困难?
  • @Verv 我添加了从原始问题修改脚本的尝试。谢谢

标签: bash


【解决方案1】:

您可以将所有文件推入一个数组,然后在随机索引处选择一个进行移动。这需要启用globstar option,以便您可以使用**/* glob 模式:

shopt -s globstar
flacfiles=(/music/**/*.flac)
cp "${flacfiles[RANDOM % ${#flacfiles[@]}]}" /test/random.flac

为了选择一个随机索引,我们将$RANDOM 取模flacfiles 数组中的元素数。

如果您想在 glob 不匹配任何内容时显示错误消息,可以使用 failglob shell 选项:

shopt -s globstar failglob
if flacfiles=(/music/**/*.flac); then
    cp "${flacfiles[RANDOM % ${#flacfiles[@]}]}" /test/random.flac
fi

此操作失败并显示错误消息

-bash: no match: music/**/*.flac

如果没有匹配的文件并且不尝试复制任何内容。

如果你确定有.flac文件,你可以忽略这个。

【讨论】:

  • @Inian 我添加了一个使用failglob的版本。
【解决方案2】:

递归

使用find 代替ls

find /music/ -iname '*.flac' -print0 | shuf -z -n1

find 部分将查找目录/music/ 中的所有flac 文件并列出它们。
shuf 打乱该列表并打印第一个条目(这是随机的,因为列表被打乱了)。

-print0-z 可以使用\NUL 分隔文件名。如果没有这些选项,将使用 \n(换行符),这是不安全的,因为文件名可以包含换行符(尽管它非常不常见)。

复制

如果您只想复制一个随机文件,则不需要while 循环。请改用替换 $()

cp "$(find /music/ -iname '*.flac' -print0 | shuf -z -n1)" /test/random.flac

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2012-04-02
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    相关资源
    最近更新 更多