我目前正在尝试将参数替换为文件路径
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/