Shell中如何替换一个字符来得到多个字符串?

Shell中如何替换一个字符来得到多个字符串?

我可以找到许多问题,并在另一个方向上找到答案,但不幸的是,不是我想要的替代品:我打算替换一个字符, 例如#在一个字符串中,例如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符(现在也被其他一些 shell 支持,包括bash)只是csh-style 大括号扩展的另一种形式。

已扩大通过外壳在调用命令之前。该命令看不到这些{0..10}

With tr '#' {0..10}(引用它,#否则它会被 shell 解析为注释的开头),tr以 ("tr", "#", "0", "1", ..., "10") 作为参数调用结束并且tr不希望有那么多争论。

在这里,您想要:

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

用于echo传递“_0.test”、“_1.test”、...、“_10.test”作为参数。

或者,如果您希望将其#转换为该{0..10}运算符,请将其转换为要计算的 shell 代码:

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}

相关内容