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:
$ 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