bash - 在 bash 脚本中将通配符作为参数替换到文件路径后如何扩展通配符?

标签 bash wildcard

我目前正在尝试将参数替换为文件路径

FILES=(~/some/file/path/${1:-*}*/${2:-*}*/*)

我正在尝试选择性地替换变量,这样如果没有参数,路径看起来像 ~/some/file/path/**/**/* 并且如果只有一,它看起来像 ~/some/file/path/arg1*/**/* 等。但是,我需要在构造文件路径后进行通配符扩展。目前似乎发生的情况是文件路径作为带有星号的单个文件路径进入 FILES。

更广泛的目标是将当前目录下两级的所有子目录传递到 FILES 变量中,除非给出参数,在这种情况下,第一个参数用于选择特定目录在第一级,第二个参数为第二级。

编辑:

此脚本生成目录,然后从中抓取随机文件,之前使用 ** 而不是 *,但它仍然有效,并正确限制要拉取的文件从给出参数时开始。问题已解决。

#!/bin/bash

mkdir dir1 dir1/a
touch dir1/a/foo.txt dir1/a/bar.txt
cp -r dir1/a dir1/b
cp -r dir1 dir2

files=(./*${1:-}/*/*)

for i in {1..10}
do
    # Get random file
    nextfile=${files[$RANDOM % ${#files[@]} ]}

    # Use file
    echo "$nextfile" || break

    sleep 0.5
done

rm -r dir1 dir2

最佳答案

我无法重现此行为。

$ files=( ~/tmp/foo/${1:-*}*/${2:-*}*/* )
$ declare -p files
declare -a files='([0]="/Users/chaduffy/tmp/foo/bar/baz/qux")'

解释为什么这预计会起作用:参数扩展发生在 glob 扩展之前,因此当 glob 扩展发生时,内容已经扩展。请参阅lhunath's simplified diagram of the bash parse/expansion process了解详情。

一个可能的解释是,你的 glob 没有匹配项,因此正在对自身进行评估。可以使用 nullglob 开关禁用此行为,这将为您提供一个空数组:

shopt -s nullglob
files=(~/some/file/path/${1:-*}*/${2:-*}*/*)
declare -p files

另一个注意事项:** 仅在已运行 shopt -s globstar 且此功能(在 4.0 中添加)可用的 shell 中具有特殊含义。在 Mac OS X 上(没有通过 MacPorts 或类似工具安装更新版本的 bash),它不存在;您需要使用 find 进行递归操作。如果您的 glob 仅在 ** 触发递归时才匹配,这可以解释相关行为。

关于bash - 在 bash 脚本中将通配符作为参数替换到文件路径后如何扩展通配符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31125007/

相关文章:

arrays - 如何循环查看命令的输出?

Linux——解析数据,用什么语言

javascript - 使用 Javascript 从 Rails 通配符命名的选择列表中获取选择值

linux - 在 makefile 中,将虚假目标声明为通配符

bash - VS Code - wsl 服务器意外关闭

bash - VScode docker-无法连接到运行Docker容器的bash

linux - 检查 xCode 的安装总是返回 true

php - 字段值上的 MySQL 通配符?

actionscript-3 - ActionScript - "Wildcard"和对象数据类型之间的区别?

java - Java 和 Scala 中的通配符导入用法