procesamiento-de-texto
Procesamiento de texto
Section titled “Procesamiento de texto”Herramientas para filtrar, transformar y resumir texto desde la línea de comandos. Se combinan con pipes para construir cadenas de procesado.
Visualización de ficheros
Section titled “Visualización de ficheros”| Comando | Uso |
|---|---|
cat f |
Muestra el fichero completo |
cat -n f |
Con números de línea |
tac f |
Muestra las líneas en orden inverso |
head -n 5 f |
Primeras 5 líneas |
tail -n 5 f |
Últimas 5 líneas |
tail -f f |
Sigue el fichero en tiempo real (útil con logs) |
less f |
Paginador (/texto busca, q sale) |
wc -l f |
Número de líneas |
nl f |
Numera las líneas |
head -n 20 fichero.txt | tail -n 5 # líneas 16 a 20tail -n +10 fichero.txt # desde la línea 10 hasta el finaltail -f /var/log/syslog # seguir un log2. grep y expresiones regulares
Section titled “2. grep y expresiones regulares”grep imprime las líneas que coinciden con un patrón.
grep "error" log.txtgrep -i "error" log.txt # ignora mayúsculasgrep -v "debug" log.txt # líneas que NO coincidengrep -n "error" log.txt # con número de líneagrep -c "error" log.txt # cuenta las líneas que coincidengrep -r "TODO" ./proyecto # búsqueda recursivagrep -w "root" /etc/passwd # palabra completagrep -o "[0-9]\+" log.txt # solo la parte que coincidegrep -E "error|fallo" log.txt # expresión regular extendidagrep -F "a.b" log.txt # texto literal (sin regex)grep -q "root" /etc/passwd # silencioso: solo devuelve el código de salidagrep -l "root" /etc/* # solo nombres de fichero con coincidenciagrep -A 2 -B 1 "error" log.txt # 2 líneas después y 1 antes (-C n: ambas)Expresiones regulares básicas
Section titled “Expresiones regulares básicas”| Patrón | Significado |
|---|---|
. |
Cualquier carácter |
^ |
Inicio de línea |
$ |
Final de línea |
[abc] |
Uno de los caracteres |
[^abc] |
Cualquiera menos esos |
[0-9] |
Rango |
* |
Cero o más repeticiones |
\+ o + (con -E) |
Una o más |
\? o ? (con -E) |
Cero o una |
{n,m} (con -E) |
Entre n y m repeticiones |
( ) y | (con -E) |
Agrupación y alternativa |
\b |
Límite de palabra |
Clases POSIX: [[:digit:]], [[:alpha:]], [[:space:]], [[:upper:]].
grep -E "^[0-9]{3}-[0-9]{4}$" telefonos.txt # formato 123-4567grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" log.txt # posibles direcciones IPv4grep "^#" config.conf # líneas que empiezan por #grep -v "^#" config.conf | grep -v "^$" # quitar comentarios y líneas vacíasgrep -P activa expresiones compatibles con Perl (\d, \K, lookahead) cuando está disponible:
grep -oP "puerto=\K\d+" config.conf3. cut, tr y paste
Section titled “3. cut, tr y paste”Extrae columnas o caracteres.
cut -d: -f1 /etc/passwd # campo 1 con delimitador :cut -d: -f1,3 /etc/passwd # campos 1 y 3cut -d, -f2- datos.csv # del campo 2 hasta el finalcut -c1-5 fichero.txt # caracteres 1 a 5cut solo admite un delimitador de un carácter; para espacios múltiples es más cómodo awk.
Traduce, elimina o comprime caracteres (trabaja con stdin).
echo "hola" | tr 'a-z' 'A-Z' # HOLAecho "a b c" | tr -s ' ' # a b c (comprime repetidos)echo "a1b2" | tr -d '0-9' # ab (elimina)echo "a1b2" | tr -cd '0-9' # 12 (conserva solo dígitos)cat fichero | tr '\n' ' ' # une líneas con espacioecho "hola" | tr 'a-zA-Z' 'n-za-mN-ZA-M' # ROT13Une ficheros línea a línea o convierte líneas en una sola.
paste a.txt b.txt # columnas separadas por tabuladorpaste -d, a.txt b.txt # separador comapaste -sd, lista.txt # todas las líneas en una, separadas por comas4. sort, uniq y wc
Section titled “4. sort, uniq y wc”sort fichero.txtsort -r fichero.txt # inversosort -n numeros.txt # orden numéricosort -u fichero.txt # elimina duplicadossort -t: -k3 -n /etc/passwd # por el campo 3, numérico, delimitador :sort -h tamanos.txt # tamaños legibles (1K, 2M)sort -V versiones.txt # orden por versión (1.2, 1.10)Elimina o cuenta líneas consecutivas repetidas; por eso suele ir después de sort.
sort fichero.txt | uniq # sin duplicadossort fichero.txt | uniq -c # cuenta cuántas veces aparece cada líneasort fichero.txt | uniq -d # solo las repetidassort fichero.txt | uniq -u # solo las que aparecen una vezPatrón clásico: ranking de frecuencias
Section titled “Patrón clásico: ranking de frecuencias”cat acceso.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head -n 10wc -l fichero.txt # líneaswc -w fichero.txt # palabraswc -c fichero.txt # bytes5. sed
Section titled “5. sed”Editor de flujo: aplica transformaciones línea a línea.
Sustituir
Section titled “Sustituir”sed 's/antiguo/nuevo/' f # primera coincidencia de cada líneased 's/antiguo/nuevo/g' f # todas las coincidenciassed 's/antiguo/nuevo/gi' f # ignorando mayúsculassed -E 's/([0-9]+)-([0-9]+)/\2-\1/' f # grupos con regex extendidased 's|/usr/bin|/opt/bin|g' f # otro delimitador para evitar escapar /Borrar e imprimir
Section titled “Borrar e imprimir”sed '3d' f # borra la línea 3sed '2,5d' f # borra de la 2 a la 5sed '/^#/d' f # borra líneas que empiezan por #sed '/^$/d' f # borra líneas vacíassed -n '5p' f # imprime solo la línea 5sed -n '5,10p' f # imprime de la 5 a la 10sed -n '/inicio/,/fin/p' f # imprime entre dos patronesInsertar y añadir
Section titled “Insertar y añadir”sed '1i Cabecera' f # inserta antes de la línea 1sed '$a Pie' f # añade tras la última líneaEditar el fichero en el sitio
Section titled “Editar el fichero en el sitio”sed -i 's/antiguo/nuevo/g' f # modifica el ficherosed -i.bak 's/antiguo/nuevo/g' f # y guarda una copia .bakConviene probar primero sin -i y comprobar el resultado.
Lenguaje orientado a columnas. Estructura: patrón { acción }.
awk '{print $1}' f # primera columna (separador: espacios)awk '{print $1, $3}' f # columnas 1 y 3awk '{print $NF}' f # última columnaawk -F: '{print $1}' /etc/passwd # separador personalizadoawk -F, -v OFS=';' '{print $1,$2}' f # cambia el separador de salidaVariables internas
Section titled “Variables internas”| Variable | Significado |
|---|---|
$0 |
Línea completa |
$1, $2… |
Columnas |
NF |
Número de campos de la línea |
NR |
Número de línea actual |
FS / OFS |
Separador de entrada / salida |
Filtrar
Section titled “Filtrar”awk 'NR > 1' f # omite la cabeceraawk '$3 > 100' f # columna 3 mayor que 100awk '/error/' f # líneas que contienen "error"awk '$1 == "root"' fawk -F: '$3 >= 1000 {print $1}' /etc/passwd # usuarios con UID >= 1000BEGIN y END
Section titled “BEGIN y END”awk 'BEGIN {print "Inicio"} {print $1} END {print "Fin"}' fawk '{suma += $2} END {print suma}' f # suma de la columna 2awk '{suma += $2} END {print suma/NR}' f # mediaawk '{c[$1]++} END {for (k in c) print k, c[k]}' f # contar por claveprintf
Section titled “printf”awk '{printf "%-10s %5d\n", $1, $2}' ffind y xargs
Section titled “find y xargs”find . -name "*.txt" # por nombrefind . -iname "*.txt" # ignorando mayúsculasfind /var/log -type f # solo ficheros (d = directorios, l = enlaces)find . -type f -size +10M # mayores de 10 MBfind . -type f -mtime -7 # modificados en los últimos 7 díasfind . -type f -mmin -30 # en los últimos 30 minutosfind . -type f -perm 644 # con permisos concretosfind . -user usuario # por propietariofind . -maxdepth 2 -name "*.sh" # limitar profundidadfind . -type f -empty # vacíosCombinar condiciones: -and (implícito), -or, -not.
find . -type f \( -name "*.jpg" -o -name "*.png" \)Ejecutar acciones
Section titled “Ejecutar acciones”find . -name "*.tmp" -deletefind . -name "*.sh" -exec chmod +x {} \; # un comando por ficherofind . -name "*.log" -exec gzip {} + # agrupa ficheros en una sola llamadaConvierte la entrada estándar en argumentos de otro comando.
find . -name "*.txt" | xargs wc -lcat urls.txt | xargs -n 1 curl -sI # un argumento por ejecuciónecho "a b c" | xargs -I{} echo "Elemento: {}"cat hosts.txt | xargs -P 4 -I{} ping -c1 {} # 4 procesos en paraleloPara nombres con espacios, usar separador nulo:
find . -name "*.txt" -print0 | xargs -0 rm| Opción | Efecto |
|---|---|
-n N |
N argumentos por ejecución |
-I{} |
Marcador donde insertar cada elemento |
-P N |
Hasta N procesos simultáneos |
-0 |
Entrada separada por caracteres nulos |
-r |
No ejecutar si la entrada está vacía |
jq para JSON
Section titled “jq para JSON”jq filtra y transforma JSON. No viene instalado por defecto (sudo apt install jq).
Dado datos.json:
{"nombre": "servidor1", "puertos": [22, 80], "activo": true}jq '.' datos.json # formateajq '.nombre' datos.json # "servidor1"jq -r '.nombre' datos.json # servidor1 (sin comillas)jq '.puertos[0]' datos.json # 22jq '.puertos[]' datos.json # un valor por líneajq '.puertos | length' datos.json # 2jq 'select(.activo == true)' datos.jsonSobre listas de objetos:
jq '.[] | .nombre' lista.jsonjq -r '.[] | "\(.nombre): \(.puerto)"' lista.jsonjq '[.[] | select(.puerto > 1024)]' lista.jsonCon APIs:
curl -s https://example.com/api/datos | jq -r '.resultado[].id'Opciones útiles: -r salida sin comillas, -c salida compacta (un objeto por línea), -e devuelve código de salida según el resultado.