Una de les grans virtuts de la línia de comandes de Linux és que pots tractar text amb petites eines que fan una sola cosa i es combinen amb canonades (|): una talla columnes, una altra ordena, una altra compta… Amb quatre o cinc d’aquestes eines pots analitzar un registre, netejar un CSV o fer un informe ràpid sense obrir cap programa.
Què eren les GNU textutils
Les GNU textutils eren el paquet del projecte GNU amb les eines per tractar fitxers de text: cat, cut, sort, uniq, wc, tr, head, tail, paste, join, nl, split… L’any 2003 es van fusionar amb les fileutils i les sh-utils en un sol paquet, les GNU coreutils, que és el que trobes avui a qualsevol distribució. Les eines són les mateixes; només ha canviat el nom del paquet.
La versió anterior d’aquest article hi incloïa grep, sed i awk. Són eines igual d’imprescindibles, però no han format mai part de les textutils: cadascuna és un paquet GNU independent. Les veuràs també aquí, perquè es fan servir juntes contínuament.
Fitxer d’exemple
$ cat persones.csv
nom,ciutat,edat
joan,Girona,34
maria,Lleida,28
pere,Girona,45
anna,Reus,28
cat: mostrar i unir fitxers
cat fitxer1.txt fitxer2.txt > resultat.txt
Tens els detalls a la comanda cat. Les seves companyes per veure trossos d’un fitxer són head (el principi), tail (el final) i tac (a l’inrevés).
cut: extreure columnes
Amb -d indiques el separador i amb -f els camps que vols:
$ cut -d, -f1,3 persones.csv
nom,edat
joan,34
maria,28
pere,45
anna,28
També pots tallar per posició de caràcter amb -c (cut -c1-4). cut només accepta un separador d’un sol caràcter i no sap tractar diversos espais seguits com un de sol: per a sortides alineades amb espais, és millor awk '{print $2}'.
sort: ordenar
sort fitxer.txt # alfabèticament
sort -r fitxer.txt # a l'inrevés
sort -n fitxer.txt # numèricament
sort -u fitxer.txt # ordena i treu les línies repetides
sort -h fitxer.txt # mides «humanes» (1K, 2M, 3G)
Per ordenar per una columna, indica el separador amb -t i la columna amb -k. Aquí, per edat de més gran a més petita, sense la capçalera:
$ tail -n +2 persones.csv | sort -t, -k3,3nr
pere,Girona,45
joan,Girona,34
anna,Reus,28
maria,Lleida,28
-k3,3 vol dir «de la columna 3 a la 3». Si només poses -k3, sort agafa des de la columna 3 fins al final de la línia.
uniq: línies repetides
uniq només detecta repeticions consecutives, per això gairebé sempre va darrere de sort:
sort fitxer.txt | uniq # treu duplicats (com sort -u)
sort fitxer.txt | uniq -c # compta quantes vegades surt cada línia
sort fitxer.txt | uniq -d # només les línies repetides
sort fitxer.txt | uniq -u # només les que surten una vegada
La combinació sort | uniq -c | sort -rn és un clàssic per fer rànquings. Quantes persones hi ha de cada ciutat:
$ tail -n +2 persones.csv | cut -d, -f2 | sort | uniq -c | sort -rn
2 Girona
1 Reus
1 Lleida
wc: comptar
$ wc persones.csv
5 5 75 persones.csv
Línies, paraules i bytes. Per a una sola cosa: wc -l (línies), wc -w (paraules), wc -c (bytes) o wc -m (caràcters, que no és el mateix que bytes si hi ha accents).
tr: canviar o esborrar caràcters
echo "Hola" | tr 'a-z' 'A-Z' # a majúscules
echo "a b c" | tr -s ' ' # redueix espais repetits a un
tr -d '\r' < windows.txt > linux.txt # treu els retorns de carro de Windows
Quedar-se només amb els números:
$ echo "telèfon: 972-12-34-56" | tr -d -c '0-9\n'
972123456
Compte: tr treballa byte a byte, i no entén les lletres accentuades. echo "Hola Món" | tr 'a-z' 'A-Z' dona HOLA MóN. Per a text amb accents, fes servir GNU sed: sed 's/.*/\U&/' dona HOLA MÓN.
paste, join i comm: combinar fitxers
paste posa fitxers un al costat de l’altre:
$ paste -d, noms.txt edats.txt
joan,34
maria,28
Amb -s posa totes les línies d’un fitxer en una de sola:
$ paste -sd, noms.txt
joan,maria
join uneix dos fitxers pel camp que tenen en comú (com un JOIN de bases de dades). Tots dos han d’estar ordenats per aquest camp:
$ cat usuaris.txt
1 joan
2 maria
$ cat ciutats.txt
1 Girona
2 Lleida
$ join usuaris.txt ciutats.txt
1 joan Girona
2 maria Lleida
comm compara dos fitxers ordenats i et diu què és només al primer, només al segon o a tots dos. Amb -12 mostra només les línies comunes:
comm -12 <(sort llista1.txt) <(sort llista2.txt)
nl i split
nl numera les línies (com cat -n, però per defecte no numera les buides):
nl fitxer.txt
split divideix un fitxer gran en trossos, per línies (-l) o per mida (-b):
split -l 1000 registre.log tros_ # tros_aa, tros_ab…
split -b 100M copia.tar.gz copia_ # per enviar-lo en parts
cat copia_* > copia.tar.gz # per tornar-lo a unir
Les companyes: grep, sed i awk
grep busca línies que contenen un patró. Tens una guia completa a l’article sobre grep.
grep "Girona" persones.csv
grep -c "Girona" persones.csv # quantes línies
grep -v "^#" config.conf # treu els comentaris
sed és un editor de flux: modifica el text a mesura que passa. L’ús més comú és substituir:
sed 's/antic/nou/g' fitxer.txt # mostra el resultat, no toca el fitxer
sed -i 's/antic/nou/g' fitxer.txt # modifica el fitxer
sed -i.bak 's/antic/nou/g' fitxer.txt # modifica'l i en desa una còpia .bak
sed -n '2,3p' fitxer.txt # només les línies 2 i 3
sed '/^pere/d' persones.csv # esborra les línies que comencen per «pere»
awk treballa per columnes i pot fer càlculs. Multiplicar per 2 la primera columna, o sumar les edats:
awk '{print $1 * 2}' numeros.txt
awk -F, 'NR > 1 {suma += $3} END {print suma}' persones.csv
En tens molts més exemples a la guia d’awk.
Combinar-les
La força d’aquestes eines és encadenar-les. Unes quantes receptes:
Les 10 IP que fan més peticions a un servidor web:
cut -d' ' -f1 /var/log/apache2/access.log | sort | uniq -c | sort -rn | head
Els noms (primera columna) de les persones de Girona, ordenats i sense repeticions:
grep "Girona" persones.csv | cut -d, -f1 | sort -u
Els 10 fitxers més grans d’un directori:
du -ah /var/log | sort -rh | head
Les paraules més freqüents d’un text:
tr -s '[:space:]' '\n' < text.txt | sort | uniq -c | sort -rn | head
Compte amb…
- No redirigeixis al mateix fitxer que llegeixes.
sort fitxer.txt > fitxer.txtel buida abans de llegir-lo. Fes servir un fitxer temporal o, ambsort, l’opció-o:sort -o fitxer.txt fitxer.txt. - L’idioma afecta l’ordre.
sortordena segons la configuració regional (LANG), i el resultat pot canviar d’un sistema a un altre. Als scripts, si necessites un ordre estable, fes servirLC_ALL=C sort. - Els CSV de debò són més complicats. Si un camp pot contenir comes entre cometes (
"Girona, Catalunya"),cutiawk -F,fallaran. Per a aquests casos, fes servir una eina que entengui CSV (per exemple,csvkitomlr, del paquetmiller).
Comandes relacionades
cat,head,taililess.grepiawk.du -sk * | sort -nr: una canonada clàssica ambsort.ls /tmp | pr -T5 -W$COLUMNS:pr, una altra de les antigues textutils.