1. Antes de abrir: texto o binario
Para el sistema, todos los archivos son lo mismo: una secuencia de bytes. La diferencia está en cómo se interpretan, y hay dos grandes familias:
| Archivo de texto | Archivo binario | |
|---|---|---|
| Sus bytes representan | Letras, números y signos | Datos en un formato propio de cada programa |
| Se lee | Directamente, con cualquier herramienta | Solo con el programa que conoce el formato |
| Ejemplos | Configuración, registros, scripts, código fuente, CSV, HTML | Programas, imágenes, audio, video, archivos comprimidos, PDF |
Las herramientas de este tema son para archivos de texto. Como en Linux la extensión no garantiza nada, según vimos en el tema 6, hay un comando que averigua de qué clase es un archivo mirando su contenido: file.
$ cd ~/practica
$ file notas.txt informe.txt fotos /usr/bin/ls
notas.txt: ASCII text
informe.txt: ASCII text
fotos: directory
/usr/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, …
file reconoce cientos de formatos: imágenes, con sus dimensiones; documentos, archivos comprimidos, y el idioma de codificación de los textos. Ante un archivo de origen dudoso, es lo primero que conviene ejecutar.
Mostrar un archivo binario con cat no lo daña, pero envía a la terminal bytes que esta interpreta como órdenes: la pantalla se llena de signos y el indicador puede quedar ilegible, con otros caracteres. Se arregla escribiendo reset y pulsando Enter, aunque no se vea lo que se teclea.
2. cat: el archivo entero
cat escribe en la pantalla el contenido completo de los archivos que recibe, uno después de otro. Lo usamos desde el tema 2:
$ cat notas.txt
Mi primer archivo
$ cat notas.txt /etc/hostname # dos archivos, uno a continuación del otro
Mi primer archivo
equipo
El segundo ejemplo explica el nombre, que viene de concatenate, encadenar. cat se creó para unir archivos; mostrar uno solo es el caso más simple de esa unión. Junto con una redirección, que veremos en el tema 23, sirve para fundir varios archivos en uno.
| Opción | Efecto |
|---|---|
-n | Numera las líneas. |
-b | Numera solo las líneas que no están vacías. |
-s | Reduce varias líneas vacías seguidas a una sola. |
-A | Muestra los caracteres invisibles: tabulaciones y finales de línea. |
cat tiene un límite evidente: no se detiene. Con un archivo de pocas líneas es ideal; con uno largo, el contenido pasa a toda velocidad y solo queda a la vista el final. Si lo ejecutas sobre un archivo enorme por error, Ctrl+C lo interrumpe.
cat es adecuado para… | No lo es para… |
|---|---|
| Archivos que entran en una pantalla. | Archivos largos: para eso está less. |
| Unir varios archivos. | Ver solo una parte: head y tail. |
| Enviar un archivo a otro comando. | Archivos binarios. |
3. Qué es una línea
Todas las herramientas de este tema, y casi todas las del bloque 6, trabajan por líneas. Conviene saber con precisión qué es una.
Una línea es una secuencia de caracteres terminada por un carácter especial, el salto de línea. Ese carácter no se ve, pero ocupa un byte en el archivo, igual que una letra.
La opción -A de cat lo hace visible, representándolo con un signo $ al final de cada línea:
$ cat -A notas.txt
Mi primer archivo$
$ ls -l notas.txt
-rw-rw-r-- 1 ana ana 18 oct 12 10:32 notas.txt
Esto resuelve una pequeña incógnita que arrastramos desde el tema 2. «Mi primer archivo» tiene 17 caracteres, contando los espacios, y el archivo mide 18 bytes: el que falta es el salto de línea que echo agregó al final.
-A muestra también las tabulaciones, como ^I. Es la manera de saber si las columnas de un archivo están separadas con espacios o con tabuladores, cosa que a simple vista no se distingue y que importa al procesarlo:
$ head -n 9 informe.txt | tail -n 1 | cat -A
tcpmux^I^I1/tcp^I^I^I^I# TCP port service multiplexer$
La misma opción diagnostica un problema clásico. Windows termina cada línea con dos caracteres en lugar de uno. Un archivo de texto creado allí y llevado a Linux se ve bien, pero cada línea termina en ^M$ en vez de $, y ese carácter sobrante hace fallar a los scripts con errores incomprensibles. Se corrige con el comando dos2unix.
4. less: leer de a una pantalla
Para un archivo que no entra en la pantalla, la herramienta es un paginador. Ya lo conocemos: es el programa que man usa para mostrar sus páginas, y que en el tema 4 usamos también con --help. Se llama less, y abre cualquier archivo:
$ less informe.txt
La pantalla se llena con el comienzo del archivo y en la última línea aparece su nombre. Las teclas son las que aprendimos para el manual:
| Tecla | Acción |
|---|---|
Barra espaciadora, b | Avanzar y retroceder una pantalla. |
| Flechas | Moverse de a una línea. |
g, G | Ir al principio y al final. |
/texto, ?texto | Buscar hacia adelante y hacia atrás. |
n, N | Coincidencia siguiente y anterior. |
q | Salir. |
less tiene tres ventajas sobre cat que lo hacen la opción por defecto para cualquier archivo que no sea mínimo. Permite ir hacia atrás. Permite buscar. Y no carga el archivo entero antes de mostrarlo: abre al instante un registro de varios gigabytes.
El nombre es una broma. El paginador original de Unix se llamaba more, «más», por el aviso que mostraba al pie de cada pantalla, y solo avanzaba. Cuando se escribió uno mejor, que también retrocedía, lo llamaron less, por el dicho less is more, «menos es más». more sigue existiendo, pero no hay motivo para preferirlo.
5. less, más allá de lo básico
Algunas funciones de less resultan muy útiles con archivos reales y no hacían falta para leer el manual:
Dentro de less | Acción |
|---|---|
50g | Ir a la línea 50. |
50% | Ir a la mitad del archivo. |
&texto | Mostrar solo las líneas que contienen ese texto. & y Enter las vuelve a mostrar todas. |
-N | Activar o quitar los números de línea. |
-S | Activar o quitar el corte de líneas largas: en lugar de doblarse, siguen hacia la derecha y se recorren con las flechas laterales. |
-i | Hacer que las búsquedas no distingan mayúsculas de minúsculas. |
F | Esperar y mostrar lo que se agregue al archivo. Ctrl+C vuelve al modo normal. |
h | La ayuda completa. |
Las que empiezan con guion son a la vez opciones de la línea de comandos: se pueden teclear dentro de less, o escribir al abrirlo.
$ less -N informe.txt # con números de línea
$ less -S /var/log/syslog # sin doblar las líneas largas
$ less +G /var/log/syslog # abrir directamente al final
$ less +/ssh informe.txt # abrir en la primera aparición de «ssh»
El filtro & es el menos conocido y uno de los más prácticos: en un registro de miles de líneas, &error deja a la vista solo las que mencionan un error, y se sigue pudiendo navegar y buscar entre ellas.
-S merece una explicación. Un registro o una tabla de datos suele tener líneas más anchas que la ventana. Dobladas, cada registro ocupa varios renglones y las columnas se desarman. Cortadas, cada línea del archivo ocupa un renglón de la pantalla, y la estructura vuelve a verse.
6. head: el principio
Muchas veces alcanza con el comienzo de un archivo para saber qué es y qué formato tiene. head muestra las primeras líneas; diez, si no se indica otra cosa:
$ head informe.txt
# Network services, Internet style
#
# Updated from https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml .
#
# New ports will be added on request if they have been officially assigned
# by IANA and used in the real-world or are needed by a debian package.
# If you need a huge list of used numbers please install the nmap package.
tcpmux 1/tcp # TCP port service multiplexer
echo 7/tcp
Diez líneas bastaron para entender el archivo: un encabezado de comentarios que explica su origen, y luego una tabla con el nombre de cada servicio de red, su número de puerto y, a veces, una descripción.
| Comando | Muestra |
|---|---|
head archivo | Las primeras 10 líneas. |
head -n 3 archivo | Las primeras 3. |
head -3 archivo | Lo mismo, en la forma abreviada. |
head -n -5 archivo | Todo menos las últimas 5. |
head -c 100 archivo | Los primeros 100 bytes, sin atender a las líneas. |
Con varios archivos, head muestra el comienzo de cada uno, precedido de un título con su nombre. Es una forma rápida de pasar revista a un directorio:
$ head -n 1 *.txt
==> informe.txt <==
# Network services, Internet style
==> notas.txt <==
Mi primer archivo
7. tail: el final
tail es el complemento: muestra las últimas líneas. Diez, por defecto.
$ tail -n 5 informe.txt
dircproxy 57000/tcp # Detachable IRC Proxy
tfido 60177/tcp # fidonet EMSI over telnet
fido 60179/tcp # fidonet EMSI over TCP
# Local services
El final es la parte que más interesa en los registros. Un programa que anota lo que hace agrega cada novedad al final de su archivo, de modo que lo último que ocurrió está en las últimas líneas. Ante una falla, tail sobre el registro correspondiente es el primer gesto.
| Comando | Muestra |
|---|---|
tail archivo | Las últimas 10 líneas. |
tail -n 3 archivo | Las últimas 3. |
tail -n +20 archivo | Desde la línea 20 hasta el final. |
tail -c 100 archivo | Los últimos 100 bytes. |
La tercera fila tiene una sintaxis que se presta a confusión, y que conviene mirar junto con su simétrica de head. En los dos comandos, un signo delante del número cambia el punto de referencia:
| Se escribe | Significa | Uso típico |
|---|---|---|
head -n 5 | Las 5 primeras. | Ver el comienzo. |
head -n -5 | Todas, salvo las 5 últimas. | Quitar un pie de página. |
tail -n 5 | Las 5 últimas. | Ver el final. |
tail -n +5 | Todas, a partir de la quinta. | Quitar un encabezado. |
El último caso es muy frecuente con archivos de datos, cuya primera línea contiene los títulos de las columnas: tail -n +2 datos.csv entrega todo salvo esa línea.
8. Un tramo del medio
No hay un comando para «las líneas 10 a 12». No hace falta: se obtienen combinando los dos anteriores con una tubería, de modo que la salida del primero sea la entrada del segundo.
$ head -n 12 informe.txt | tail -n 3 # las 12 primeras, y de ellas las 3 últimas
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
$ tail -n +10 informe.txt | head -n 3 # desde la 10, y de ellas las 3 primeras
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
El ejemplo es pequeño, y muestra la manera de pensar de la terminal: en lugar de un comando grande que lo haga todo, dos comandos simples, cada uno con una tarea, conectados. Las tuberías son el tema 24, y a esta altura ya las usamos varias veces sin ceremonia.
Con cat -n delante se puede comprobar el resultado, porque cada línea llega con su número: cat -n informe.txt | head -n 12 | tail -n 3. Más adelante veremos una herramienta que extrae un rango de líneas directamente, sed, en el tema 29.
9. tail -f: seguir un archivo en vivo
tail tiene una opción que lo convierte en otra herramienta. Con -f, de follow, muestra las últimas líneas y no termina: se queda esperando, y escribe cada línea nueva en el momento en que alguien la agrega al archivo.
Para verlo hacen falta dos terminales. En la primera se sigue un archivo; en la segunda se le agregan líneas. Usamos /tmp, para no dejar rastros:
$ touch /tmp/diario.log
$ tail -f /tmp/diario.log
← queda esperando, sin indicador
$ echo "Arranca el servicio" >> /tmp/diario.log
$ echo "Conexión aceptada" >> /tmp/diario.log
$ tail -f /tmp/diario.log
Arranca el servicio
Conexión aceptada
Cada línea aparece en la primera terminal en el instante en que se ejecuta el echo en la segunda. Los dos signos >> agregan texto al final de un archivo; los explicamos en el tema 23. Para terminar el seguimiento se pulsa Ctrl+C: es el caso, anunciado en el tema 2, de un comando que no termina por sí solo.
Este es el modo en que se observa un sistema en funcionamiento. Se deja un tail -f sobre el registro de un servicio en una ventana, se provoca la situación a estudiar en otra, y se lee lo que el servicio va anotando mientras ocurre.
| Comando | Efecto |
|---|---|
tail -f archivo | Sigue el archivo. |
tail -n 50 -f archivo | Muestra las últimas 50 líneas y luego sigue. |
tail -n 0 -f archivo | Solo lo nuevo, sin mostrar nada de lo anterior. |
tail -F archivo | Sigue el nombre: si el archivo se reemplaza por uno nuevo, continúa con el nuevo. |
tail -f a.log b.log | Sigue varios a la vez, indicando de cuál viene cada línea. |
La -F mayúscula es la que conviene para los registros del sistema. Estos se rotan periódicamente: el archivo actual se guarda con otro nombre y se empieza uno nuevo, vacío. Un tail -f se quedaría mirando el viejo, en silencio; -F se da cuenta y pasa al nuevo.
Dentro de less, la tecla F hace lo mismo, con la ventaja de que Ctrl+C devuelve al paginador y se puede retroceder y buscar en lo que pasó.
10. wc: contar
wc, de word count, no muestra el contenido de un archivo sino sus dimensiones:
$ wc notas.txt
1 3 18 notas.txt
$ wc informe.txt
361 1773 12813 informe.txt
361 1773 12813 informe.txt
│ │ │ │
│ │ │ └─ el archivo
│ │ └─ bytes
│ └─ palabras
└─ líneas
Los tres números son siempre líneas, palabras y bytes, en ese orden. Una «palabra» es cualquier secuencia de caracteres separada por espacios, tabulaciones o saltos de línea. Con opciones se pide uno solo:
| Opción | Cuenta |
|---|---|
-l | Líneas. Es, con mucha diferencia, la más usada. |
-w | Palabras. |
-c | Bytes. |
-m | Caracteres. |
-L | La longitud de la línea más larga. |
$ wc -l *.txt
361 informe.txt
1 notas.txt
362 total
$ echo "año" | wc -c # bytes
5
$ echo "año" | wc -m # caracteres
4
Con varios archivos, wc agrega una línea con el total. Los dos últimos comandos muestran la diferencia entre bytes y caracteres, que anticipamos al hablar de los nombres en el tema 6. La palabra «año» tiene tres letras, más el salto de línea que añade echo: cuatro caracteres. Pero la ñ ocupa dos bytes, y por eso son cinco. En un texto en español, -c y -m dan números distintos.
wc -l cuenta en rigor los saltos de línea. Por eso un archivo cuya última línea no termina en salto de línea da uno menos de lo esperado. Es raro, y explica alguna diferencia de una unidad.
11. También leen de una tubería
En varios ejemplos estos comandos no recibieron un nombre de archivo, sino la salida de otro comando. Es una propiedad común a todos, y la que los hace tan útiles:
Cuando no se les indica un archivo, cat, less, head, tail y wc leen de su entrada. Conectados con una tubería a otro comando, procesan lo que este escribe como si fuera un archivo.
| Comando | Qué se obtiene |
|---|---|
ls -l /etc | less | Un listado largo, leído de a una pantalla. |
ls /usr/bin | wc -l | Cuántos programas hay en ese directorio. |
ls -lS /var/log | head -n 6 | Los archivos más grandes: el total y las cinco primeras líneas. |
history | tail -n 20 | Los últimos veinte comandos. |
find ~ -type f | wc -l | Cuántos archivos hay en el directorio personal. |
De ahí salen tres costumbres que conviene adquirir. Cuando un comando produce más de una pantalla, | less al final. Cuando solo interesa cuántos resultados hay, | wc -l. Y cuando interesa una muestra, | head.
Hay una diferencia de salida que ya apareció en la sección anterior: leyendo de una tubería, wc no muestra ningún nombre, porque no hay archivo que nombrar. Solo el número, que es lo cómodo para usarlo en un script.
12. Otras formas de mirar
Algunas herramientas menores completan el repertorio. No hace falta memorizarlas; sí saber que existen:
| Comando | Qué hace | Para qué sirve |
|---|---|---|
nl archivo | Numera las líneas, como cat -b, con más control del formato. | Preparar un texto para citar líneas. |
tac archivo | Muestra el archivo con las líneas en orden inverso: es cat al revés. | Leer un registro empezando por lo más reciente. |
zcat, zless | Lo mismo que cat y less, sobre archivos comprimidos .gz. | Leer los registros antiguos de /var/log sin descomprimirlos. |
strings archivo | Extrae los fragmentos de texto legible que hay dentro de un binario. | Espiar qué mensajes contiene un programa. |
xxd archivo | Muestra los bytes en hexadecimal, junto a su equivalente en texto. | Examinar un binario, o un texto con caracteres extraños. |
La última permite ver por dentro lo que cat no puede mostrar. Las primeras posiciones de un programa de Linux, por ejemplo:
$ head -c 16 /usr/bin/ls | xxd
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
A la izquierda, la posición; en el centro, los dieciséis bytes en hexadecimal; a la derecha, los que corresponden a un carácter visible, y un punto en lugar de los demás. Los cuatro primeros son una marca que identifica el formato: las letras ELF, el de los ejecutables de Linux. Así trabaja el comando file de la sección 1: reconoce las marcas del comienzo de cada archivo.
13. Explorar un archivo desconocido
Con todas las piezas se puede fijar un procedimiento para la situación más habitual: alguien te pasa un archivo, o lo encuentras en un directorio del sistema, y quieres saber qué es sin sorpresas.
- Tamaño y fecha, con
ls -lh archivo. ¿Son kilobytes o gigabytes? medir - Tipo, con
file archivo. Si no es texto, las herramientas de este tema no sirven. identificar - Cantidad de líneas, con
wc -l archivo. medir - El principio, con
head archivo. Suele explicar el formato. mirar - El final, con
tail archivo. En un registro, es lo más reciente. mirar - El resto, con
less archivo, buscando con/lo que interese. leer
Aplicado a nuestro archivo de práctica, los cinco primeros pasos dicen: 13 KB, texto, 361 líneas, un encabezado de comentarios seguido de una tabla de servicios y puertos, y una sección final vacía para servicios locales. En menos de un minuto, y sin haber leído el archivo, se sabe qué es y cómo está organizado.
Y el criterio para elegir herramienta:
| Quiero… | Comando |
|---|---|
| Saber qué clase de archivo es | file archivo |
| Ver un archivo corto | cat archivo |
| Leer un archivo largo, o buscar en él | less archivo |
| Ver cómo empieza | head archivo |
| Ver lo último que se escribió | tail archivo |
| Ver lo que se va escribiendo | tail -f archivo |
| Saltear la primera línea | tail -n +2 archivo |
| Ver las líneas 20 a 30 | head -n 30 archivo | tail -n 11 |
| Saber cuántas líneas tiene | wc -l archivo |
| Ver espacios, tabulaciones y finales de línea | cat -A archivo |
El archivo /tmp/diario.log de la sección 9 puede quedar donde está: desaparecerá al reiniciar.
Mirar es la mitad del trabajo con texto. La otra mitad es cambiarlo. En el tema 13 aprendemos a editar un archivo sin salir de la terminal, con nano, y lo indispensable de vim.
14. Resumen
- Los archivos son de texto o binarios.
fileindica de qué clase es uno, mirando su contenido y no su extensión. catmuestra archivos enteros, uno tras otro. Sirve para archivos cortos;-nnumera las líneas y-Arevela los caracteres invisibles.- Una línea termina en un carácter de salto de línea, que ocupa un byte. Casi todas las herramientas de texto trabajan por líneas.
lesses el paginador: permite avanzar, retroceder y buscar, y abre al instante archivos enormes. Se sale conq.- Dentro de
less,&textofiltra líneas,-Nlas numera y-Sevita que las largas se doblen. headmuestra las primeras líneas ytaillas últimas; diez por defecto, o las que indique-n.tail -n +Nmuestra desde la línea N hasta el final;head -n -N, todo menos las últimas N.- Un tramo intermedio se obtiene combinando
headytailcon una tubería. tail -fsigue un archivo y muestra lo que se le agrega, hasta que se lo interrumpe con Ctrl+C. Es la forma de observar un registro en vivo.wccuenta líneas, palabras y bytes.wc -les la forma más usada.- Todos estos comandos leen de una tubería cuando no reciben un archivo:
| less,| heady| wc -lse aplican a la salida de cualquier comando. - Ante un archivo desconocido: tamaño, tipo, cantidad de líneas, principio, final, y recién entonces el contenido.
15. Preguntas de repaso
Intenta responder cada una antes de abrir la respuesta.
1. ¿Cómo se averigua si un archivo es de texto antes de mostrarlo?
Con file archivo, que examina el contenido e informa el tipo.
2. Mostraste un binario con cat y la terminal quedó ilegible. ¿Qué haces?
Escribir reset y pulsar Enter, aunque no se vea lo que se teclea. Restablece la terminal.
3. ¿De dónde viene el nombre cat y qué hace con varios archivos?
De concatenate. Muestra los archivos uno a continuación del otro, como si fueran uno solo.
4. El archivo notas.txt contiene un texto de 17 caracteres y mide 18 bytes. ¿Qué es el byte restante?
El salto de línea que termina la única línea del archivo. Se lo puede ver con cat -A, que lo representa con un signo $.
5. ¿Qué ventajas tiene less sobre cat para un archivo largo?
Muestra de a una pantalla, permite retroceder y buscar, y no necesita leer el archivo entero antes de empezar.
6. Dentro de less, ¿cómo se muestran solo las líneas que contienen la palabra «error»?
Con &error y Enter. Un & solo, seguido de Enter, vuelve a mostrar todas.
7. ¿Qué muestran head -n 3 y tail -n 3?
Las tres primeras líneas y las tres últimas, respectivamente.
8. ¿Qué diferencia hay entre tail -n 5 y tail -n +5?
La primera muestra las últimas cinco líneas. La segunda, todas las líneas a partir de la quinta.
9. Escribe un comando que muestre las líneas 50 a 60 de un archivo.
head -n 60 archivo | tail -n 11, o bien tail -n +50 archivo | head -n 11.
10. ¿Qué hace tail -f y cómo se termina?
Muestra las últimas líneas del archivo y queda esperando, escribiendo cada línea nueva que se le agrega. Se termina con Ctrl+C.
11. ¿Cuándo conviene tail -F en lugar de tail -f?
Con los registros que se rotan. Si el archivo se reemplaza por uno nuevo con el mismo nombre, -F pasa a seguir el nuevo, mientras que -f seguiría mirando el anterior.
12. ¿Qué significan los tres números de wc archivo?
La cantidad de líneas, de palabras y de bytes, en ese orden.
13. ¿Por qué wc -c y wc -m pueden dar resultados distintos?
Porque -c cuenta bytes y -m cuenta caracteres. Las letras con tilde y la ñ ocupan más de un byte cada una.
14. ¿Cómo se cuenta cuántos archivos hay en un directorio?
Enviando el listado a wc -l: ls directorio | wc -l. Para incluir los subdirectorios, find directorio -type f | wc -l.
15. ¿Qué pasos conviene seguir ante un archivo desconocido?
Ver su tamaño con ls -lh, su tipo con file, su cantidad de líneas con wc -l, su principio con head, su final con tail, y recién entonces abrirlo con less.
Para practicar
- Ejecuta
filesobre/etc/passwd,/usr/bin/bash,/etc,/biny algún archivo de/usr/share/man/man1. ¿Qué tipo informa para cada uno? - Aplica el método de la sección 13 a
/etc/passwd. ¿Cuántas líneas tiene, y qué separa sus campos? - Abre
informe.txtconless -N. Ve a la línea 100, buscahttp, recorre las coincidencias, y luego filtra con&udp. - Muestra las líneas 20 a 25 de
informe.txtcon sus números, usandocat -n,headytail. - Muestra
informe.txtsin su encabezado de comentarios, es decir, a partir de la línea 9, y cuenta cuántas líneas quedan. - Con
cat -A, averigua si/etc/passwdy/etc/fstabusan tabulaciones o espacios. - Repite la experiencia de la sección 9 con dos terminales. Prueba luego
tail -n 0 -fy observa la diferencia. - Si tu usuario puede leerlo, ejecuta
tail -f /var/log/syslogy, en otra terminal,logger "Hola desde la terminal". ¿Qué aparece? - Averigua cuántas páginas tiene la sección 1 del manual contando los archivos de
/usr/share/man/man1. - Compara
echo "canción" | wc -cconecho "cancion" | wc -cy explica la diferencia. Luego mira los bytes conecho "ñ" | xxd.