如何在序列的外壳括号扩展中使用$ variable?


33

我想$var in在bash中使用带范围的shell括号扩展。简单地推杆{$var1..$var2}是行不通的,所以我就“横向”了。

以下工作有效,但有点麻烦。

# remove the split files
echo rm foo.{$ext0..$extN} rm-segments > rm-segments
source rm-segments

有没有更“正常”的方式?

Answers:


26

您可能要尝试:

eval rm foo.{$ext0..$extN}

不确定这是否是最佳答案,但肯定是最佳答案。


rrh!:(我看不到明显的东西……谢谢:)
Peter.O 2011年

4
在bash中,{}扩展发生在$扩展之前,因此,除了使用eval或其他技巧使表达式两次通过之外,没有其他方法可以执行此操作。
mattdm 2011年

6
我只是“得到”了!...有没有括号扩展{$one..$three},因为它不是支柱膨胀,在这种情况下,预计整数的有效形式......它只是变成了$ VAR扩张后的有效形式,其eval然后通过相同的处理,生成正常支架序列膨胀...... 1 2 3 QED)...总结:简单存在一个的一对括号简化版,触发括号扩展的...只有一个有效的形式的触发器它。
Peter.O 2011年

@fred:欢迎:-)
asoundmove,2011年

当使用像这样的变量时a={0..9}; echo $a;,没有括号扩展。使用eval,它可以工作。所以我认为@mattdm的解释很好。
dr0i

20

正如你已经意识到,{1..3}膨胀到1 2 3{foo..bar}还是{$foo..$bar}不触发括号展开,而后者随后被扩大,以取代$foo$bar它们的值。

GNU(例如非嵌入式Linux)的后备之处是 seq命令。

for x in `seq $ext0 $extN`; do rm foo.$x; done

另一种可能性。如果foo.包含外壳特殊字符,则为

rm `seq $ext0 $extN | sed 's/^/foo./'`

最简单的解决方案是使用zsh,在rm foo.{$ext0..$extN}您想要的地方做什么。


感谢您的选择。很高兴看到它们全部分组..我将坚持使用bash和eval ... eval非常简单,因为我知道幕后发生的一切;所以这不再是问题。不需要因为骑手而换一匹好马:)...
Peter.O 2011年

1

当其他答案讨论在中使用evalseqbash,您可以for在算术上下文中使用传统的C样式循环。变量ext0extN((..))导致循环运行的范围内扩展。

for (( idx = ext0; idx <= extN; idx++ )); do
    [[ -f "$foo.$idx" ]] || { printf "file %s does not exist" "$foo.$idx" >&2 ; continue }
    rm "$foo.$idx"
done

如果您正在寻找一种最佳方法并且避免使用多个rm命令,则可以使用一个临时占位符来存储文件名结果并调用rm

 results=()
 for (( idx = ext0; idx <= extN; idx++ )); do
     [[ -f "$foo.$idx" ]] || { printf "file %s does not exist" "$foo.$idx" >&2 ; continue }
     results+=( "$foo.$idx" )
 done

现在rm在扩展数组上调用命令

 rm -- "${results[@]}"

0
    function f_over_range {
        for i in $(eval echo {$1..$2}); do
            f $i
        done
    }

    function f {
        echo $1
    }

    f_over_range 0 5
    f_over_range 00 05

笔记:

  • 使用eval会暴露命令注入的安全风险
  • Linux将打印“ 00 \ n01 \ n02..etc”,而OSX将打印“ 1 \ n2 \ n ... etc”
  • 使用seq或C样式进行循环将不匹配括号扩展对前导零的处理
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.