Bash中括弧拡張に変数を使用できますか?

Bash中括弧拡張に変数を使用できますか?

私が達成しようとしている作業の一種の疑似コードは次のとおりです。

#!/bin/bash

# I already have the variable below figured out (positive integer):
numlines=$([returns number of lines containing specific characters in a file])

# This is basically what I want to do with it:
for i in {1..$numlines}; do
    # the part below is already figured out as well:        
    do some other stuff
done

「{1..n}」シーケンスに実際の数字を挿入すると、コマンドラインから正しく実行できます。ここに変数を含めることができるかどうか、それを行う方法を知りたいです。

  • 私はすでにexport試しました。
  • 変数自体をシーケンス内の中かっこ内に入れてみました。{1..${numlines}}
  • 私はそれが拡張されることを願って二重引用符で囲んでみました。{1.."$numlines"}
  • 私は脱出しようとしました${1..\$numlines}

set -[something]この変数を拡張するにはコマンドを使用する必要がありますか?私はどんな形の使い方も試してみましたがeval…役に立ちませんでした。

私が何か簡単か曖昧なものを見逃しているのか、それとも時間を無駄にする前にこれが可能かを知る必要があります。

私は実質を1つに集めることができる。本物必要に応じて機能させる方法は次のとおりです。しかし、可能であればこれを避け、正しい方法を学びたいです。

答え1

残念ながら、変数拡張は中括弧拡張の後に発生するため、その拡張(AFAIK)では変数を使用できません。

幸いなことに、同じことをするツールがあります。

for i in $(seq 1 $numlines); do
    # stuff
done

seqGNU coreutilsはPOSIXでこれを行う方法を知りません。

答え2

確かに。整数変数を増やす for ループが必要な場合は、次の形式を使用します。forリング整数変数を増やします(またはより一般的にはループ変数に対して算術演算を実行します)。

for ((i=1; i<=numlines; i++)); do … done

この設定はbash(およびksh93とzsh)では機能しますが、通常のshでは機能しません。通常のshでは、whileループとテスト([ … ])構造を使用します。

i=1
while [ "$i" -le "$numlines" ]; do
  i=$((i+1))
done

答え3

seqTom Hunterが指摘したように、この問題を解決する一般的な方法であることを避ける必要がある場合は、eval絶対にできる次の手順を実行します(ただし推奨しません)。

eval 'for i in {1..'$numlines'}; do echo $i; done'

{}拡張を避けることでPOSIXを維持し、数学的および整数の比較のみを実行できます$numlines

while [ ! "$numlines" -eq 0 ]; do
     echo "$numlines"
     : $((numlines-=1))
done

POSIXの外側にはCスタイルのループbashkshあります。zshfor

for((i=0; i<numlines; i++)); do echo $i; done

関連情報