Acessando o número/variável da iteração de expansão de chave bash

Acessando o número/variável da iteração de expansão de chave bash

Pergunta:

É possível acessar qual número de uma iteração do bash está sendo processado atualmente?

Psuedo-Comando

mv {1..5}.something.{1..5} $x1.$x2.something
  • Nota: Esta é uma representação lógica; uma amostra não funcional.

Pseudo-Saída

mv 1.something.1 1.1.something
mv 1.something.2 1.2.something
...
mv n.something.m n.m.something
  • Onde n e m são ambos a iteração de sua respectiva expansão de chaves.

Explicação

Estou familiarizado com loops como:

for x in {1..10}; do echo -n "$x "; done

Como você pode ver, o bash está configurando a iteração para $x. Desejo saber se é possível e como acessar a variável que o bash usa quando não estou definindo qual variável usar. Quando bash recebe umexpansão de cintasem uma variável para iterar, ela deve fazê-lo [internamente] de alguma forma. Espero que esta variável esteja acessível em tempo de execução do script.

Obrigado a todo o pessoal#bash

Responder1

Você está entendendo mal como funciona a expansão de chaves. Por favor, releia o comentário de Dennis Williamson acima.

Você está pensando que, quando escrevo mv foo.{1,2,3} bar, o shell está, na verdade, invocando o comando várias vezes, como se você tivesse digitado:

mv foo.1 bar
mv foo.2 bar
mv foo.3 bar

Se isso fosse verdade, então sua pergunta faria sentido: o shell está executando vários comandos e por isso precisa manter uma lista.

Mas não é isso que está acontecendo. A expansão do suporte se expandeum único argumentoentão invoca a linha de comando resultanteum tempo. Portanto, para o exemplo acima, o shell vê que o argumento foo.{1,2,3}contém expansão de chaves e expande esse argumento em três argumentos foo.1 foo.2 foo.3. Em seguida, ele insere essa expansão na linha de comando no lugar do argumento entre chaves e continua analisando a linha de comando. Quando terminar, o shell executa um comando, que ficaria assim:

mv foo.1 foo.2 foo.3 bar

Então, sim, provavelmente quando o shell está expandindo esse argumento entre chaves, ele mantém uma lista, mas não há como acessar essa lista na expansão de outros argumentos porque a expansão entre chaves está totalmente concluída e todas as informações sobre a expansão são usadas e esquecidas por o momento em que os outros argumentos estão sendo analisados.

De qualquer forma, a única maneira de tal argumento ser útil seria se o shell estivesse executando vários comandos, o que não está. Para executar vários comandos você precisa usar um loop real; a expansão de chaves não fará isso.

Quanto a $_, essa é uma construção Perl que pode ser usada no lugar de uma variável de loop (como xno seu exemplo de loop), portanto não é realmente relevante para a expansão de chaves.

Responder2

Especificamente mv, você pode simplesmente usar o -vsinalizador para ver o que está sendo processado no momento. Como @DennisWilliamson apontou, nenhuma variável é definida para a sequência expandida de chaves - Writing echo {1..5}é equivalente a Writing echo 1 2 3 4 5. Compare com echo "$foo"- Não há como saber qual variável foi echoeditada.

Responder3

por que você não usa sua própria variável para contar o número da iteração e repeti-lo. Se você quiser ver o que está acontecendo na execução, execute-o com a opção -x. Como bash -x lhe dirá onde está ex. Mas sem especificar o que você está tentando alcançar, é difícil ajudar.

informação relacionada