シェルで 1 つの文字を置き換えて複数の文字列を取得するにはどうすればよいでしょうか?

シェルで 1 つの文字を置き換えて複数の文字列を取得するにはどうすればよいでしょうか?

反対方向の答えを持つ質問はたくさんあるが、残念ながら私が望むような答えは見つからない。私は文字を置き換える、 のような#文字列で、例えばtest#asdf、のようなシーケンスで{0..10} 文字列のシーケンスを取得するこの例では ですtest0asdf test1asdf test2asdf test3asdf test4asdf test5asdf test6asdf test7asdf test8asdf test9asdf test10asdf

試してみました、他の人から:

  • echo '_#.test' | tr # {0..10}(使用法をスローします)
  • echo '_#.test' | sed -r 's/#/{0..10}/g'(戻り値_{0..10}.test
  • echo '_#.test' | sed -r 's/#/'{0..10}'/g'(最初はうまくいきますが、その後sed: can't read (...) no such file or directory

この問題に対する有効なアプローチは何ですか?

編集、まだコメントしていないかもしれないので: 文字列が別のプログラムから渡されたので、この文字を置き換える文字列で を使用する必要があります#。ただし、最初に別の文字に置き換えることはできます。

答え1

演算子{0..10} zsh(現在は を含む他のいくつかのシェルでもサポートされています) は、 スタイルの中括弧展開bashの別の形式です。csh

拡大されるシェルによってコマンドを呼び出す前に、 . を追加します。コマンドはこれらを認識しません{0..10}

tr '#' {0..10}(#引用符で囲まないと、シェルによってコメントの開始として解析されます)は、tr引数として ("tr", "#", "0", "1", ..., "10") を使用して呼び出され、trそれほど多くの引数は期待されません。

ここでは、次のことが必要になります。

echo '_'{0..10}'.test' 

引数としてecho「_0.test」、「_1.test」、...、「_10.test」が渡されます。

#または、それをその演算子に変換したい場合は{0..10}、評価されるシェル コードに変換します。

eval "$(echo 'echo _#.test' | sed 's/#/{0..10}/')"

引数としてeval渡される場所。echo _{0..10}.test

(そんなことをすることをお勧めするわけではありませんが)。

答え2

あなたはできるスプリット区切り文字の文字列からプレフィックスとサフィックスを取得し、中括弧展開を使用して名前を生成します。

str='test#asdf'
IFS='#' read -r prefix suffix <<<"$str"
names=( "$prefix"{0..10}"$suffix" )
declare -p names
declare -a names='([0]="test0asdf" [1]="test1asdf" [2]="test2asdf" [3]="test3asdf" [4]="test4asdf" [5]="test5asdf" [6]="test6asdf" [7]="test7asdf" [8]="test8asdf" [9]="test9asdf" [10]="test10asdf")'

答え3

を使用する必要がありますか#? おそらく を使用できますか%d?

$ for i in {1..10}; do printf "_%d.test " "$i"; done
_1.test _2.test _3.test _4.test _5.test _6.test _7.test _8.test _9.test _10.test

答え4

私はそうするだろうパラメータ拡張:

$ var='test#asdf'
$ for i in {1..10}; do echo "${var/\#/"$i"}"; done
test1asdf
test2asdf
test3asdf
test4asdf
test5asdf
test6asdf
test7asdf
test8asdf
test9asdf
test10asdf

拡大​${parameter/pattern/string}

  • (この場合は)の展開をとり、$parameter$var
  • 最初の出現を置き換えますpattern(エスケープされた#-は、/#文脈上「文字列の先頭を置換する」という特別な意味を持ちますが、これは避けたいものです)
  • string"$i"私たちの場合には)

あるいは、#%dに置き換えて、 のフォーマット文字列として使用することもできますprintf

printf "${var/\#/%d}\\n" {1..10}

関連情報