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: -
- Resuelva cualquier patrón para poder sustituirlo.
- 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 lsdvd
y 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 sed
comando busca los números siguientes Title:
y Chapters:
en la salida de lsdvd
. sed
luego almacena esos números en \1
y \2
respectivamente. sed
genera 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 expression
como una expresión aritmética y evaluarla", mientras que y#x
es una expresión aritmética que significa "tratar x
como un número base y
y convertirlo a decimal". Entonces, por ejemplo, 2#10
se evalúa como 2
(ya que 10 representa 2 en base 2), 10#10
se evalúa como 10
(ya que convertir un número de base 10 a decimal no hace nada) y 3#4
arroja un error (ya que "4" no es un símbolo legal en base 3) . Más información está disponible en la ARITHMETIC EVALUATION
sección de man bash
.
Entonces el sed
comando simplemente genera una cadena que se ve así: cells[$((10#x))]=$((10#y))
donde x
y y
son 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 cells
matriz.
Ésa es la esencia del asunto.