Abaixo está algum tipo de pseudo-código para o que estou tentando realizar:
#!/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
Eu posso executá-lo bem na linha de comando, inserindo o número real na sequência `{1..n} '. Eu só preciso saber se é possível incluir uma variável aqui e como proceder.
- Eu tentei
export
ing-lo - Eu tentei colocar a variável em si entre chaves dentro da sequência:
{1..${numlines}}
- Eu tentei colocá-lo entre aspas duplas na esperança de expandir:
{1.."$numlines"}
- Eu tentei escapar do
$
:{1..\$numlines}
Preciso usar um set -[something]
comando para que essa variável seja expandida? Eu até tentei algumas formas de usar eval
... tudo sem sucesso.
Eu só preciso saber se há algo simples ou obscuro que estou perdendo ou se isso é possível antes que eu perca mais tempo com isso.
Eu poderia criar uma maneira realmente, muito tola de fazê-lo, para fazê-lo funcionar conforme necessário, mas gostaria de evitar isso, se possível, e aprender o caminho certo para fazê-lo.
bash
shell-script
scripting
rubynorails
fonte
fonte
Respostas:
Infelizmente, não há como usar uma variável nessa expansão (AFAIK), uma vez que a expansão variável ocorre após a expansão entre chaves.
Felizmente, há uma ferramenta que faz o mesmo trabalho.
seq
é do GNU coreutils; não faço ideia de como fazê-lo no POSIX.fonte
seq
é bom para sistemas GNU e, se bem me lembro, o OSX mais recente. Em outros sistemas BSD, pode-se usar jot .seq
funciona perfeitamente. Muito obrigado pela sua pronta resposta.{16..1}
?$(seq $numlines 1)
não funcionou. Eu acho que posso sempreman seq
, mas apenas me perguntando se alguém sabia do que se pensava.for i in $(seq $numlines -1 1)
seq ${numlines} -1 0
Certo. Se você deseja um loop for que incrementa uma variável inteira, use a forma do
for
loop que incrementa uma variável inteira (ou, geralmente, executa aritmética nas variáveis do loop).Essa construção funciona no bash (e ksh93 e zsh), mas não no sh simples. No sh simples, use um loop while e a
[ … ]
construção test ( ).fonte
Se você deve evitar
seq
, o que, como Tom Hunt aponta, parece ser a solução usual para isso, entãoeval
definitivamente pode fazê-lo (embora eu não o incentive):Você pode permanecer no POSIX evitando a expansão {} e simplesmente fazendo comparações matemáticas e inteiras em
$numlines
:Do lado de fora da POSIX,
bash
eksh
ezsh
também tem de estilo Cfor
lacetes:fonte
seq
funcionado bem no meu cenário e pareceu ser a solução mais simples, é bom saber que existem outras alternativas (até POSIX). Obrigado por isso.eval
; se você tiver expansão de chaves, você tem o loop de estilo C.eval
exemplo era o mais simples e teria me poupado de ter que procurar uma maneira alternativa de fazer isso usandoseq
. Owhile
loop é um pouco volumoso para mim. Eu gosto de manter as coisas curtas e agradáveis, e nunca consegui que ofor
loop no estilo C funcionasse, fornecendoi
o valor de 0 ou 1. Ele nunca retornou corretamente e sempre estava um pouco fora. Tenho certeza de que poderia ser ajustado para funcionar corretamente, mas essas são definitivamente soluções úteis, no entanto.eval
abordagem é problemática se houver algo não trivial dentro do corpo do loop. Eu imagino que não seria muito legível se você precisasse aninhar dois desses loops.