
Posso encontrar muitas perguntas com respostas na outra direção, mas infelizmente não naquela que gostaria que meus substitutos: pretendosubstituir um caractere, como #
,em uma corda, como test#asdf
, com uma sequência, como{0..10}
para obter uma sequência de strings, neste exemplo test0asdf test1asdf test2asdf test3asdf test4asdf test5asdf test6asdf test7asdf test8asdf test9asdf test10asdf
.
Eu tentei, de outros:
echo '_#.test' | tr # {0..10}
(joga uso)echo '_#.test' | sed -r 's/#/{0..10}/g'
(retorna_{0..10}.test
)echo '_#.test' | sed -r 's/#/'{0..10}'/g'
(funciona para o primeiro, depois eu recebosed: can't read (...) no such file or directory
)
Qual é uma abordagem funcional para este problema?
Edite, como não posso comentar ainda: tenho que usar #
na string, na qual esse caractere deve ser substituído, como a string passada de outro programa. Eu poderia primeiro substituí-lo por outro caractere.
Responder1
O {0..10}
zsh
operador (agora também suportado por alguns outros shells, incluindo bash
) é apenas outra forma de csh
expansão de chaves no estilo -.
Está expandidopela cascaantes de chamar o comando. O comando não vê esses arquivos {0..10}
.
With tr '#' {0..10}
(citando que #
caso contrário é analisado pelo shell como o início de um comentário), tr
termina sendo chamado com ("tr", "#", "0", "1", ..., "10") como argumentos e tr
não espera tantos argumentos.
Aqui, você iria querer:
echo '_'{0..10}'.test'
para echo
serem passados "_0.test", "_1.test", ..., "_10.test" como argumentos.
Ou se você quiser que isso #
seja traduzido nesse {0..10}
operador, transforme-o em código shell para ser avaliado:
eval "$(echo 'echo _#.test' | sed 's/#/{0..10}/')"
onde eval
está sendo passado echo _{0..10}.test
como argumentos.
(não que eu recomendaria fazer algo assim).
Responder2
Você podedividira string no delimitador, capture o prefixo e o sufixo e use a expansão de chaves para gerar os nomes:
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")'
Responder3
Você tem que usar #
? Talvez você possa usar %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
Responder4
eu faria isso comexpansão de parâmetros:
$ var='test#asdf'
$ for i in {1..10}; do echo "${var/\#/"$i"}"; done
test1asdf
test2asdf
test3asdf
test4asdf
test5asdf
test6asdf
test7asdf
test8asdf
test9asdf
test10asdf
A expansão${parameter/pattern/string}
- leva a expansão de (no nosso caso, ) e
$parameter
$var
- substitui a primeira ocorrência de
pattern
(o escape#
–/#
tem um significado especial no contexto, "substituir no início da string", que queremos evitar) com string
("$i"
no nosso caso)
Como alternativa, você pode substituir #
por %d
e usá-lo como string de formato para printf
:
printf "${var/\#/%d}\\n" {1..10}