我可以找到许多问题,并在另一个方向上找到答案,但不幸的是,不是我想要的替代品:我打算替换一个字符, 例如#
,在一个字符串中,例如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}