在bash脚本中将通配符替换为文件路径之后如何扩展通配符?

时间:2015-06-29 20:31:12

标签: bash wildcard

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

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

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

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

编辑:

此脚本生成目录,然后从中获取随机文件,之前有**而不是*,但它仍然有效,并且正确地限制文件在给定参数时从中拉出。问题已解决。

#!/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

1 个答案:

答案 0 :(得分:4)

我无法重现这种行为。

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

要解释为什么,预计这会有效:参数扩展在全局扩展之前发生,因此在进行全局扩展时,内容已经扩展。有关详细信息,请参阅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的shell中具有特殊含义,并且此功能(在4.0中添加)可用。在Mac OS X上(没有通过MacPorts或类似版本安装更新版本的bash),它不存在;您希望使用find进行递归操作。如果你的glob只在**触发递归时匹配,这将解释有问题的行为。