A continuación hay una especie de pseudocódigo para lo que estoy tratando de lograr:
#!/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
Puedo ejecutarlo bien desde la línea de comando insertando el número real en la secuencia `{1..n} '. Solo necesito saber si es posible incluir una variable aquí y cómo hacerlo.
- He tratado
export
ing se - He intentado poner la variable en sí misma entre llaves dentro de la secuencia:
{1..${numlines}}
- He intentado ponerlo entre comillas dobles con la esperanza de que se expanda:
{1.."$numlines"}
- He intentado escapar de
$
:{1..\$numlines}
¿Necesito usar un set -[something]
comando para que esta variable se expanda? Incluso he intentado algunas formas de uso eval
... todo en vano.
Solo necesito saber si hay algo simple u oscuro que me estoy perdiendo o si esto es posible antes de perder más tiempo.
Podría reunir una forma muy, muy dura de hacerlo para que funcione según sea necesario, pero me gustaría evitarlo si es posible y aprender la forma correcta de hacerlo.
bash
shell-script
scripting
rubynorails
fuente
fuente
Respuestas:
Desafortunadamente, no hay forma de usar una variable en esa expansión (AFAIK), ya que la expansión variable ocurre después de la expansión de la llave.
Afortunadamente, hay una herramienta que hace el mismo trabajo.
seq
es de GNU coreutils; No tengo idea de cómo hacerlo en POSIX.fuente
seq
es bueno para los sistemas GNU y, si no recuerdo mal, el OSX más reciente. En otros sistemas BSD, uno puede usar jot en su lugar.seq
funciona perfectamente. Muchas gracias por su pronta respuesta.{16..1}
?$(seq $numlines 1)
no funcionó. Supongo que siempre puedoman seq
, pero me pregunto si alguien sabía de la cabeza.for i in $(seq $numlines -1 1)
seq ${numlines} -1 0
Por supuesto. Si desea un bucle for que incremente una variable entera, use la forma del
for
bucle que incremente una variable entera (o más generalmente realiza aritmética en la (s) variable (s) del bucle).Esta construcción funciona en bash (y ksh93 y zsh), pero no en sh simple. En sh simple, use un bucle while y la
[ … ]
construcción test ( ).fuente
Si debe evitar
seq
, lo que, como señala Tom Hunt, parece ser la solución habitual para esto, entonceseval
definitivamente puede hacerlo (sin embargo, no lo recomendaría):Puede permanecer en POSIX evitando la expansión {}, y simplemente hacer comparaciones de matemáticas y enteros en
$numlines
:Fuera de POSIX,
bash
yksh
yzsh
también tienen estilo Cfor
bucles:fuente
seq
bien funcionó bien para mi escenario y parecía ser la solución más simple, es bueno saber que hay otras alternativas (incluso POSIX). Gracias por esto.eval
; si tiene expansión de llaves, tiene el bucle de estilo C.eval
ejemplo fue el más simple y me habría evitado tener que buscar una forma alternativa de hacerlo usandoseq
. Elwhile
bucle es un poco voluminoso para mí. Me gusta mantener las cosas cortas y dulces, y nunca pude hacerfor
que funcione el bucle de estilo C dandoi
el valor de 0 o 1. Nunca regresó correctamente y siempre estaba un poco apagado. Estoy seguro de que podría modificarse para que funcione correctamente, pero estas son definitivamente soluciones útiles, no obstante.eval
enfoque es problemático si hay algo no trivial dentro del cuerpo del bucle. Me imagino que no sería muy legible si necesitaras anidar dos de estos bucles.