Usando eval y sed para realizar conteo y control de script

Usando eval y sed para realizar conteo y control de script

Siguiendo el problema original descrito aquí: - Copiar capítulos de un DVD para separar archivos

... ¿Alguien podría ayudarnos a comprender qué hace el siguiente código?

# count Titles, and count Cells per title. 
# eg. ${cell[1]}      is the Count of Cells for the first title
#     ${cell[titles]} is the Count of Cells for the last title 
eval $(lsdvd | sed -n 's/Title: \([0-9]\+\), .* Chapters: \([0-9]\+\), Cells: .*/cells[$((10#\1))]=$((10#\2));/p')
titles=${#cells[@]} title_num=2 from_cell=1 to_cell=${cell[title_num]}

Nos gustaría hacer lo mismo y hemos intentado utilizar el código. Lamentablemente, no nos funciona y, debido a que nuestra comprensión es limitada, no podemos depurarlo.

Entendemos la idea básica de usar sed pero no podemos entender cómo logra: -

  1. Resuelva cualquier patrón para poder sustituirlo.
  2. Produzca cualquier patrón para sustituirlo.

Además, su acoplamiento aquí con eval() está fuera de nuestro alcance. Además, hay tres usos de # que tampoco entendemos.

Por favor ayuda. Gracias.

Respuesta1

En primer lugar, como no lo mencionaste, supongo que se trata de un script bash.

El brillo de alto nivel de estas dos líneas es que extraen el número del título y el número del capítulo de la salida lsdvdy los almacenan en una matriz llamada cells.

Es probable que el código proporcionado no funcione porque to_cell=${cell[title_num]}en la última línea debería estar to_cell=${cells[title_num]}.

Aquí hay un desglose más detallado:

El sedcomando busca los números siguientes Title:y Chapters:en la salida de lsdvd. sedluego almacena esos números en \1y \2respectivamente. sedgenera una cadena con el formato cells[$((10#\1))]=$((10#\2)), reemplazando las referencias de barra invertida con el título y los números de capítulo.

Creo que la sintaxis también te confunde $((10#x)). Aquí está el desglose: $((expression))en bash significa "tratar expressioncomo una expresión aritmética y evaluarla", mientras que y#xes una expresión aritmética que significa "tratar xcomo un número base yy convertirlo a decimal". Entonces, por ejemplo, 2#10se evalúa como 2(ya que 10 representa 2 en base 2), 10#10se evalúa como 10(ya que convertir un número de base 10 a decimal no hace nada) y 3#4arroja un error (ya que "4" no es un símbolo legal en base 3) . Más información está disponible en la ARITHMETIC EVALUATIONsección de man bash.

Entonces el sedcomando simplemente genera una cadena que se ve así: cells[$((10#x))]=$((10#y))donde xy yson números. Eso se pasa a eval. Creo que ya sabes lo suficiente como para darte cuenta de que evaluar esta cadena solo da como resultado una asignación de matriz estándar en bash, ya que después de evaluar las expresiones aritméticas, la cadena tiene el aspecto cells[x]=y.

La última línea es sólo una asignación de variable adicional, con un truco. ${#cells[@]}simplemente evalúa la cantidad de elementos en la cellsmatriz.

Ésa es la esencia del asunto.

información relacionada