Tengo un proceso en el que necesito copiar todas las imágenes de una página web. Solía ejecutar este proceso con xmllint
, que procesará un archivo XML o HTML e imprimirá las entradas que especifique. Pero cuando mi proveedor de host de servidor actualizó sus sistemas, no incluyeron xmllint
. Entonces tuve que encontrar otra forma de extraer una nómina de imágenes de una página HTML. Resulta que puedes hacer esto en Bash.
Puede que no crea que Bash pueda analizar archivos de datos, pero puede hacerlo con un pensamiento inteligente. Bash, como otros shells de UNIX anteriores, puede analizar las líneas de una en una desde un archivo a través de la función incorporada read
proclamación.
Por defecto, el read
proclamación escanea una segmento de datos y la divide en campos. Generalmente, read
divide los campos usando espacios y tabulaciones, con nuevas líneas al final de cada segmento, pero puede cambiar este comportamiento configurando el Separador de campo interno (IFS
) valía y el delimitador de final de segmento (-d
).
Para analizar un archivo HTML usando read
, selecciona el IFS
a un símbolo maduro que (>
) y el delimitador a un símbolo beocio que (<
). Cada vez que Bash escanea una segmento, analiza hasta la futuro <
(el aparición de una rótulo HTML) luego divide esos datos en cada >
(el final de una rótulo HTML). Este código de muestra toma una segmento de entrada y divide los datos en TAG
y VALUE
variables:
nave IFS='>' read -d '<' TAG VALUE
Exploremos cómo funciona esto. Considere este simple archivo HTML:
some text
La primera vez read
analiza este archivo, se detiene en el primer <
símbolo. Ya que <
es el primer carácter de esta entrada de muestra, lo que significa que Bash encuentra una prisión vacía. La resultante TAG
y VALUE
las cadenas todavía están vacías. Pero eso está adecuadamente para mi caso de uso.
La próxima vez que Bash lee la entrada, obtiene img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" />↲
con una nueva segmento acordado antiguamente de la alt, y se detiene antiguamente de la <
símbolo en la futuro segmento. Entonces read
divide la segmento en el >
símbolo, que deja TAG
con img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" /
y VALUE
con una nueva segmento vacía.
La tercera vez read
analiza el archivo HTML, obtiene p>some text
. Bash divide la cuerda en el >
Resultando en TAG
conteniendo p
y VALUE
con some text
.
Ahora que entiendes cómo usar read
, es dócil analizar un archivo HTML más generoso con Bash. Comience con una función Bash indicación xmlgetnext
para analizar los datos usando read
, ya que lo hará una y otra vez en el asunto. Nombré mi función xmlgetnext
para recordarme que este es un reemplazo para Linux xmllint
software, pero podría haberlo conocido fácilmente htmlgetnext
.
xmlgetnext () { nave IFS='>' read -d '<' TAG VALUE }
Ahora apasionamiento a eso xmlgetnext
función para analizar el archivo HTML. Esta es mi completa htmltags
asunto:
#!/bin/sh # print a list of all html tags xmlgetnext () { nave IFS='>' read -d '<' TAG VALUE } cat $1 | while xmlgetnext ; do echo $TAG ; done
La última segmento es la esencia. Recorre el archivo usando xmlgetnext
para analizar el HTML, e imprime solo el TAG
entradas. Y por como echo
opera con los separadores de campo tipificado, cualquier segmento como img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" /
que contienen una nueva segmento se imprimen en una sola segmento, como img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png" alt="My logo" /
.

Para obtener solo la nómina de imágenes, ejecuto la salida de este script a través de grep
para imprimir solo las líneas que tienen un img
rótulo al principio de la segmento.