bash 基于变量内容的大括号扩展不起作用
bash brace expansion based on variable content not working
如何让 bash 扩展它在传递给 mkdir 的变量中找到的任何内容?
到目前为止,我已经尝试使用 eval
和 bash -c
,但似乎没有任何效果
LEVEL_1=1,2,3
LEVEL_2=a,b,c
DATA_L1="/tmp/{$LEVEL_1}"
DATA_L2="$DATA_L1/{$LEVEL_2}"
for LINE in $(cat file.txt) ; do
#"cat" here returns values like
#$DATA_L2/yy/data
mkdir -pv $LINE #it actually contains e.g. this $DATA_L2/yy/data
done
我希望这会扩展到
mkdir -p /tmp/1/a/yy/data
mkdir -p /tmp/2/a/yy/data
mkdir -p /tmp/3/a/yy/data
mkdir -p /tmp/1/b/yy/data
mkdir -p /tmp/2/b/yy/data
mkdir -p /tmp/3/b/yy/data
mkdir -p /tmp/1/c/yy/data
mkdir -p /tmp/2/c/yy/data
mkdir -p /tmp/3/c/yy/data
我怀疑你的问题是你有 两层 扩展,即使你没有在你的问题中表明这一点。也就是说,你显示:
mkdir -pv $DATA_L2/yy/data
如果你简单地添加一个 eval
就可以了:
eval mkdir -pv $DATA_L2/yy/data
但是在你的循环中,你实际上并不是 运行 上面的命令。我认为你 运行 是这样的:
mkdir -pv $LINE
如果我们在 mkdir
前面加上一个 echo
,我们可以看到:
echo mkdir -pv $LINE
结果:
mkdir -pv $DATA_L2/yy/data
并且:
eval echo mkdir -pv $LINE
结果:
mkdir -pv /tmp/{1,2,3}/{a,b,c}/yy/data
如果你加倍 eval:
eval eval echo mkdir -pv $LINE
你得到你想要的东西:
mkdir -pv /tmp/1/a/yy/data /tmp/1/b/yy/data /tmp/1/c/yy/data /tmp/2/a/yy/data /tmp/2/b/yy/data /tmp/2/c/yy/data /tmp/3/a/yy/data /tmp/3/b/yy/data /tmp/3/c/yy/data
但是双重 eval
是一个非常好的迹象,需要重新考虑您解决问题的方法。
我怀疑这是一个 XY problem,但一个选项可能是数组和 for 循环,类似于:
numbers=(1 2 3)
letters=(a b c)
dir="/tmp"
for letter in "${letters[@]}"; do
for number in "${numbers[@]}"; do
echo mkdir -pv "$dir/$number/$letter/yy/data"
done
done
输出:
mkdir -pv /tmp/1/a/yy/data
mkdir -pv /tmp/2/a/yy/data
mkdir -pv /tmp/3/a/yy/data
mkdir -pv /tmp/1/b/yy/data
mkdir -pv /tmp/2/b/yy/data
mkdir -pv /tmp/3/b/yy/data
mkdir -pv /tmp/1/c/yy/data
mkdir -pv /tmp/2/c/yy/data
mkdir -pv /tmp/3/c/yy/data
如何让 bash 扩展它在传递给 mkdir 的变量中找到的任何内容?
到目前为止,我已经尝试使用 eval
和 bash -c
,但似乎没有任何效果
LEVEL_1=1,2,3
LEVEL_2=a,b,c
DATA_L1="/tmp/{$LEVEL_1}"
DATA_L2="$DATA_L1/{$LEVEL_2}"
for LINE in $(cat file.txt) ; do
#"cat" here returns values like
#$DATA_L2/yy/data
mkdir -pv $LINE #it actually contains e.g. this $DATA_L2/yy/data
done
我希望这会扩展到
mkdir -p /tmp/1/a/yy/data
mkdir -p /tmp/2/a/yy/data
mkdir -p /tmp/3/a/yy/data
mkdir -p /tmp/1/b/yy/data
mkdir -p /tmp/2/b/yy/data
mkdir -p /tmp/3/b/yy/data
mkdir -p /tmp/1/c/yy/data
mkdir -p /tmp/2/c/yy/data
mkdir -p /tmp/3/c/yy/data
我怀疑你的问题是你有 两层 扩展,即使你没有在你的问题中表明这一点。也就是说,你显示:
mkdir -pv $DATA_L2/yy/data
如果你简单地添加一个 eval
就可以了:
eval mkdir -pv $DATA_L2/yy/data
但是在你的循环中,你实际上并不是 运行 上面的命令。我认为你 运行 是这样的:
mkdir -pv $LINE
如果我们在 mkdir
前面加上一个 echo
,我们可以看到:
echo mkdir -pv $LINE
结果:
mkdir -pv $DATA_L2/yy/data
并且:
eval echo mkdir -pv $LINE
结果:
mkdir -pv /tmp/{1,2,3}/{a,b,c}/yy/data
如果你加倍 eval:
eval eval echo mkdir -pv $LINE
你得到你想要的东西:
mkdir -pv /tmp/1/a/yy/data /tmp/1/b/yy/data /tmp/1/c/yy/data /tmp/2/a/yy/data /tmp/2/b/yy/data /tmp/2/c/yy/data /tmp/3/a/yy/data /tmp/3/b/yy/data /tmp/3/c/yy/data
但是双重 eval
是一个非常好的迹象,需要重新考虑您解决问题的方法。
我怀疑这是一个 XY problem,但一个选项可能是数组和 for 循环,类似于:
numbers=(1 2 3)
letters=(a b c)
dir="/tmp"
for letter in "${letters[@]}"; do
for number in "${numbers[@]}"; do
echo mkdir -pv "$dir/$number/$letter/yy/data"
done
done
输出:
mkdir -pv /tmp/1/a/yy/data
mkdir -pv /tmp/2/a/yy/data
mkdir -pv /tmp/3/a/yy/data
mkdir -pv /tmp/1/b/yy/data
mkdir -pv /tmp/2/b/yy/data
mkdir -pv /tmp/3/b/yy/data
mkdir -pv /tmp/1/c/yy/data
mkdir -pv /tmp/2/c/yy/data
mkdir -pv /tmp/3/c/yy/data