Obtener los primeros, los últimos o los caracteres anteriores y posteriores de un archivo y el número de ocurrencias con head, tail y grep

Escrito por el .
gnu-linux planeta-codigo
Comentarios

GNU
Linux

Algunos archivos de texto tienen un tamaño de cientos de megas, a veces incluso sin ningún salto de línea. Visualizar el contenido de estos archivos en una aplicación con interfaz gráfica no suele ser posible porque la aplicación se queda bloqueada al intentar cargar tan enormes archivos. Incluso tampoco puede ser posible con un editor mucho más ligero como vim. Hacer un cat del archivo tampoco es útil.

Sin embargo, sigue siendo necesario ver parte del contenido de estos archivos de texto grande para validar que el contenido de los mismos es el correcto. La opción que se puede utilizar es ver los primeros o últimos caracteres o lineas con los comandos head o tail usándolos de la siguiente forma.

1
2
3
4
5
6
$ # Primeros o últimos 100 caracteres de un archivo
$ head -c 100 archivo.txt
Lorem ipsum dolor sit amet consectetur adipiscing elit pulvinar et praesent, egestas fermentum mauri

$ tail -c 100 archivo.txt
ultricies, a dictumst velit dapibus leo pellentesque dictum dui ligula aliquam eu dignissim rhoncus.
1
2
3
4
5
6
7
$ # Primeras o últimas 2 lineas de un archivo
$ head -n 2 archivo.txt
Lorem ipsum dolor sit amet consectetur adipiscing elit pulvinar et praesent, egestas fermentum mauris phasellus non nec rutrum nibh accumsan, placerat natoque interdum dui duis viverra molestie id parturient. Imperdiet commodo viverra arcu ridiculus blandit interdum litora bibendum felis ac purus, eu facilisi habitasse ultrices nisl magnis lobortis phasellus turpis velit vestibulum faucibus, auctor sagittis consequat quis cubilia inceptos donec enim gravida mus. Lacinia felis cras leo porta imperdiet tellus ridiculus convallis praesent ante, dapibus laoreet nibh dictumst penatibus a euismod nisi nulla, luctus lacus porttitor neque magnis sed molestie curae quisque. Hac volutpat curabitur laoreet ultrices est nibh parturient quam libero, faucibus ac metus gravida quis venenatis aliquam placerat cubilia, vel ligula litora dapibus dignissim auctor rhoncus at.

$ tail -n 2 archivo.txt

Bibendum hendrerit sociosqu id libero neque, ad mollis donec consequat sagittis, tempus litora morbi nisi. Augue gravida aliquet rhoncus porta odio dui auctor velit erat lectus magna phasellus fringilla, quam praesent class cursus blandit nulla curabitur nostra feugiat consequat egestas cubilia, tortor magnis senectus volutpat ad urna semper himenaeos nascetur luctus posuere interdum. Nam quisque aliquet convallis taciti maecenas euismod vulputate mauris commodo et eleifend vel duis ultricies, a dictumst velit dapibus leo pellentesque dictum dui ligula aliquam eu dignissim rhoncus.
1
2
3
4
5
6
7
Lorem ipsum dolor sit amet consectetur adipiscing elit pulvinar et praesent, egestas fermentum mauris phasellus non nec rutrum nibh accumsan, placerat natoque interdum dui duis viverra molestie id parturient. Imperdiet commodo viverra arcu ridiculus blandit interdum litora bibendum felis ac purus, eu facilisi habitasse ultrices nisl magnis lobortis phasellus turpis velit vestibulum faucibus, auctor sagittis consequat quis cubilia inceptos donec enim gravida mus. Lacinia felis cras leo porta imperdiet tellus ridiculus convallis praesent ante, dapibus laoreet nibh dictumst penatibus a euismod nisi nulla, luctus lacus porttitor neque magnis sed molestie curae quisque. Hac volutpat curabitur laoreet ultrices est nibh parturient quam libero, faucibus ac metus gravida quis venenatis aliquam placerat cubilia, vel ligula litora dapibus dignissim auctor rhoncus at.

Proin sapien viverra nisl posuere dapibus commodo senectus aptent dui nam est tempor primis, dignissim vehicula pharetra et augue hendrerit tincidunt metus mauris curae mus eu. Quam habitasse natoque gravida cras class porttitor fringilla facilisi, phasellus mauris hendrerit et montes enim libero, suspendisse id fermentum lacus molestie purus blandit. Vivamus interdum nisi eleifend suscipit vulputate faucibus suspendisse felis curae, sodales pharetra cubilia vehicula proin velit turpis sapien ad, cursus molestie erat aliquam ridiculus rhoncus duis eu.

Mollis venenatis felis suscipit mauris fusce at massa sociosqu conubia, hac sociis aptent ut netus vestibulum nostra sed dictumst, nec non eget magna vulputate cum pellentesque arcu. Congue pharetra luctus justo curabitur turpis mi semper nibh laoreet fames, vehicula quam maecenas dui magna scelerisque dictum diam tortor, sociis massa facilisi cum viverra duis erat urna fusce. Urna interdum nisl class fames quam cum suscipit ultrices hendrerit ullamcorper, sagittis nullam aliquam porta tellus aptent fringilla iaculis vitae, vivamus vestibulum conubia elementum semper id himenaeos nunc convallis.

Bibendum hendrerit sociosqu id libero neque, ad mollis donec consequat sagittis, tempus litora morbi nisi. Augue gravida aliquet rhoncus porta odio dui auctor velit erat lectus magna phasellus fringilla, quam praesent class cursus blandit nulla curabitur nostra feugiat consequat egestas cubilia, tortor magnis senectus volutpat ad urna semper himenaeos nascetur luctus posuere interdum. Nam quisque aliquet convallis taciti maecenas euismod vulputate mauris commodo et eleifend vel duis ultricies, a dictumst velit dapibus leo pellentesque dictum dui ligula aliquam eu dignissim rhoncus.

Como programador no es raro trabajar con archivos de más de 100 MiB en los que el texto no contiene saltos de línea y el contenido es una sola línea como es el caso de un archivo en formato XML utilizado para intercambiar información entre dos aplicaciones. Estos archivos por su tamaño y sin saltos de línea se les atragantan a los editores de texto gráficos como Visual Studio Code e incluso a la opción más ligera basada en texto como vim.

En ete caso también es necesaria una forma de comprobar el contenido del archivo o contar el número de ocurrencias de un determinado patrón. La herramienta de línea de comandos grep es una gran ayuda en estos dos casos. Suponiendo un archivo XML que contiene elementos con un tag de precio se desea comprobar que estos elementos tienen un valor válido. Utilizando grep y una expresión regular se obtienen las etiquetas price, una en cada línea. El parámetro -E indica que se utilizan una expresión regular y el parámetro -o indica que cada coincidencia se emita en una línea nueva.

1
2
3
4
$ grep -E -o "<price>[^<]*</price>" archivo.xml
<price>1.0</price>
<price>2.0</price>
<price>3.0</price>
1
2
<?xml version="1.0" encoding="UTF-8"?>
<products><product><name>A</name><price>1.0</price></product><product><name>B</name><price>2.0</price></product><product><name>C</name><price>3.0</price></product></products>

En caso de no ser un archivo estructurado como XML o querer obtener los 15 caracteres anteriores o posteriores de una coincidencia se utiliza un comando grep similar cambiando la expresión regular.

1
2
3
4
$ grep -E -o ".{0,15}price.{0,15}" archivo.xml
<name>A</name><price>1.0</price></p
<name>B</name><price>2.0</price></p
<name>C</name><price>3.0</price></p

Para contar el número de coincidencias en el archivo se puede combinar el comando grep utilizando la opción -o para que emita cada coincidencia en cada línea y el comando wc con la opción -l para que cuente el número de líneas de entrada. Utilizando una tubería entre ambos comandos es posible contar el número de coincidencias en un archivo.

1
2
$ grep -E -o "<product>" archivo.xml | wc -l
3

En este caso el XML es muy pequeño y un editor de texto es capaz de abrirlo perfectamente pero un archivo de texto a partir unas cuantas decenas de MiB se le atraganta a los editores incluso a los basados en texto y en el caso querer hacer comprobaciones una buena alternativa o la única es recurrir a los comandos head, tail, grep y wc.