Hlavní navigace

Hrátky z řádky: tr, sed, awk a ti další

19. 5. 2008
Doba čtení: 3 minuty

Sdílet

Opět se setkáváme u pravidelné pondělní dávky tipů a triků z černé řádky. V dnešním povídání opustíme zajímavé ssh a podíváme se na některé užitečné příkazy, které se nám hodí pro práci s textem. Ukážeme si třeba tr, sed, awk, cut a samozřejmě to, co dokáží dohromady a k čemu se dají využít.

tr

Začneme programem tr. Čte data ze standardního vstupu, transformuje je dle zadání a posílá na standardní výstup. Díky přesměrování vstupů a výstupů (které jsme si již dříve vysvětlovali) nám umožní snadno zpracovávat soubory. Zde několik ukázek. První změní velikost písmen v souboru:

$ tr "[:lower:]" "[:upper:]" < /etc/resolv.conf

Můžeme třeba zaměnit znak „e“ za „o“:


$ cat /etc/resolv.conf | tr "e" "o"

Můžete také například chtít naformátovat ošklivý nepřehledný soubor tak, že mezery nahradíme tabelátory. Vstup vypadá takto:

$ cat osklivy_soubor
1. 2,13 8,3 OK
2. 0,00 1,3 ERROR
3. 2,16 5,5 OK

Hezčí výstup:

$ cat osklivy_soubor | tr " " "\t"
1.      2,13    8,3     OK
2.      0,00    1,3     ERROR
3.      2,16    5,5     OK

Pokud se naopak chceme zbavit nějakého znaku, použijte parametr  -d:

$ cat osklivy_soubor | tr -d ","

Praktičtější asi bude ukázka nahrazení desetinné čárky tečkou:

$ cat osklivy_soubor | tr "," "."

sed

Podobně funguje program sed. Jedná se o neinteraktivní textový editor. Sed čte řádky ze standardního vstupu a vykonává s nimi zadané příkazy, výsledek pak zobrazuje na standardním výstupu. Sed dále podporuje regulární výrazy. Několik příkladů. Toto nám zamění slova v zadaném textu:

$ echo "maly priklad" | sed 's/maly/VELKY/'
VELKY priklad

Pro náhradu řetězce v celém souboru stačí zadat:

$ sed 's/retez1/retez2/g' soubor > soubor2

Při použití regulárních výrazů získáváme mocného pomocníka. Toto nám odstraní všechny komentáře v souboru (začínají znakem #) a zároveň odstraní prázdné řádky:

$ sed '/^#/d; /^ *$/d'  /cesta/k/souboru

Ještě jedna praktická ukázka využití sedu. Chceme zkopírovat část souboru, konce dat, které nás zajímají, jsou určené nějakým výrazem:

$ sed '/koncovy_retezec/q' /etc/rc.conf

awk

Awk je také často používaný program pro práci s textem. Syntaxe je následující:

$ awk 'program' [soubor]

Program je série pravidel, která mohou obsahovat vzor, akci nebo obojí. Akce je uzavřena do {}. Když je ve vstupu nalezen vzor, vykoná se příslušná akce. Tento příklad nám ze souboru resolv.conf zobrazí pouze řádky obsahující slovo nameserver:

$ awk '/nameserver/ {print}' /etc/resolv.conf

Následující příklad zobrazí jen druhý sloupec našeho souboru. Všimněte si, že chybí vzor, proto bude akce aplikována na všechny řádky souboru:

$ awk '{print $2}' osklivy_soubor

V předchozím příkladu samo awk poznalo, že jsou sloupce oddělené mezerou a správně zobrazilo druhý sloupec. V případě jiného oddělovače sloupců si také poradíme. Chceme třeba vědět, který uživatel používá jaký shell:

$ cat /etc/passwd | awk -F: '{print $1 " " $7}'

cut

Při výběru sloupce nám může také posloužit program cut. Hodí se v případě, že si nedokážete zapamatovat komplexní syntaxi awk. Jeho použití je snadné:

$ cut -d : -f 1,7 /etc/passwd

Když známe pevně danou pozici sloupečku, můžeme použít parametr  -c:

$  uptime
 4:33PM  up 44 days, 11:26, 1 user, load averages: 0.00, 0.01, 0.00

$  uptime | cut -c 10-19,28-34
up 44 days 1 user

Podobná věc, kterou bash umí a není tak často používaná, jsou substringy. Spousta lidí je řeší právě pomocí awk a cut. Ale zkuste si toto:

$ text="muj pokusny text"
$ echo ${text:4:7}
pokusny

Teď už praktičtější ukázky, vrátíme se k souboru /etc/passwd. Když nás bude zajímat třeba jen četnost jednotlivých shellů:

$ cut -d : -f 7 /etc/passwd | sort | uniq -c

Dostaneme podobný výsledek:

   1 /bin/sh
  20 /usr/sbin/nologin
   9 /usr/local/bin/bash

Pokud je výpis dlouhý a chceme jej třeba sestupně setřídit, stačí doplnit:

$ cut -d : -f 7 /etc/passwd | sort | uniq -c | sort -rn
  20 /usr/sbin/nologin
   9 /usr/local/bin/bash
   1 /bin/sh

Zajímá-li vás, které příkazy spouštíte nejčastěji:

UX DAy - tip 2

$ history | awk '{print $2}' | sort | uniq -c | sort -rn | head

Zpracování více souborů

Co se může hodit při práci s více soubory? Může se například stát, že je budete chtít přejmenovat na malá písmena, nahradit mezery podtržítkem nebo třeba nějak zkonvertovat soubory. Použijeme podobný skript:

#!/bin/sh

for f in *; do
    mv "$f" "`echo $f | tr ' ' '_' `"
done

V případě odstranění diakritiky, je systém stejný, jen se místo tr použije například iconv (nedávno probírané), cstocs, sed či něco dalšího. Když chceme například hromadně zkonvertovat obrázky, postup bude následující:

mkdir zmenseno

for f in *.jpg; do
   # convert je z balíku ImageMagick
   convert "$f" -resize 800x600 "zmenseno/$f"
done

Byl pro vás článek přínosný?

Autor článku

Petr Macek studoval aplikovanou informatiku na Jihočeské univerzitě, pracuje jako síťový specialista ve firmě Kostax, s. r. o. Baví ho především FreeBSD, sítě a monitoring Cacti.