Linux: Kniha kouzel, vanilková příchuť 2.14 (15. července 2022)
Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé

17. Zpracování textových souborů

Řada 2.x vanilkové příchuti Linuxu: Knihy kouzel je od 15. července 2022 do 1. března 2025 ve stavu dlouhodobé pasivní údržby; nahlášené chyby budou opravovány, ale aktivní vývoj se již věnuje jiným projektům. Máte-li zájem pokračovat v tvorbě Linuxu: Knihy kouzel pro novější verze linuxových operačních systémů, kontaktujte autora nebo rovnou vytvořte odnož.

1. Úvod

Tato kapitola se zabývá nástroji pro řazení, filtrování, analýzu, konverzi a jiné zpracování textových souborů. Nezabývá se však komplexními nástroji jako GNU awk, sed či Perl, kterým budou věnovány samostatné kapitoly.

Textové soubory se vyznačují tím, že jsou tvořeny posloupností řádek (v této kapitole zvaných „záznamy“) tvořených řetězci znaků z tzv. znakové sady. V souboru jsou znaky uloženy ve formě jednobajtových či vícebajtových sekvencí, jejichž význam určuje použité kódování znaků (v dnešní praxi téměř výhradně UTF-8 nebo jeho podmnožina ASCII).

Většina nástrojů používaných v této kapitole je vyvíjena v rámci projektu GNU.

2. Definice

  • Kódování znaků (character encoding) je určitá reprezentace znakové sady textu pomocí bajtů a jejich sekvencí v souboru či paměti. U textových souborů uvažujeme výhradně kódování UTF-8, případně jeho podmnožinu ASCII. Soubory v jiných kódováních sice také můžeme zpracovávat, ale obvykle je výhodnější je nejprve převést na UTF-8.
  • Znak (character) je základní jednotka textu, které je kódováním znaků přiřazen nějaký význam a binární reprezentace. Např. „A“ je v UTF-8 znak, který znamená písmeno A a je reprezentován bajtem o hodnotě 65. „\n“ je v UTF-8 znak, který znamená konec řádku a je reprezentován bajtem o hodnotě 10.
  • Řetězec (string) je libovolná posloupnost znaků, i prázdná či tvořená jedním znakem.
  • Záznam je zobecnění pojmu „řádka“ v textovém souboru. Textový soubor se dělí na jednotlivé záznamy podle jejich zakončení ukončovačem záznamu (record separator), což je typicky znak konce řádky „\n“ nebo nulový bajt „\0“. Záznamy se číslují od 1.
  • Záznam může být brán jako celek, nebo může být dál dělen na sloupce (fields). Existuje několik metod dělení záznamu na sloupce, nejčastější je použití určitého znaku ASCII jako „oddělovače sloupců“ (field separator). Sloupce se v každém záznamu číslují od 1.
  • Záplata je speciální textový soubor, který obsahuje záznam o změnách mezi dvěma verzemi jednoho nebo více textových souborů. Využití záplat je v dnešní době zřídkavé.

V této kapitole rozlišuji následující formáty textových souborů:

  • TXT – záznamy ukončeny „\n“, na sloupce se nedělí.
  • TXTZ – záznamy ukončeny „\0“, na sloupce se nedělí.
  • TSV – záznamy ukončeny „\n“, sloupce se dělí tabulátorem („\t“) nebo jiným znakem ASCII (např. v /etc/passwd se dělí znakem „:“).
  • TSVZ – záznamy ukončeny „\0“, sloupce se oddělují tabulátorem („\t“) nebo jiným znakem ASCII.
  • pevná šířka sloupců – záznamy ukončeny „\n“, sloupce (kromě posledního) jsou zarovnány na pevný počet znaků pomocí mezer.

3. Zaklínadla: Konverze

3/1 Konverze ukončení řádky

@Windows nebo linux na linux (na místě/rourou)#1
sed -Ei 's/\r//g' soubor
... | tr -d \\r | ...
@Windows nebo linux na Windows (na místě/rourou)#2
sed -Ei 's/\r*$/\r/' soubor
... | sed -E 's/\r*$/\r/' | ...
@Mac OS na linux (na místě/rourou)#3
LC_ALL=C sed -zEi 'y/\\r/\\n/' soubor
... | tr \\r \\n | ...
@linux na Mac OS (na místě/rourou)#4
LC_ALL=C sed -zEi 'y/\\n/\\r/' soubor
... | tr \\n \\r | ...

3/2 Konverze kódování znaků

@konvertovat soubor do/z UTF-8#1 (1)
iconv -f "vstupní kódování" -t UTF-8 [-o "výstupní-soubor"] [vstupní-soubor]
iconv -f UTF-8 -t "cílové kódování[//IGNORE]" [-o "výstupní-soubor"] [vstupní-soubor]
@konvertovat soubor do ASCII s transliterací#2 (2)
iconv -f "vstupní kodování" -t "ASCII//TRANSLIT" [-o "výstupní-soubor"] [vstupní-soubor]
@vypsat úplný seznam podporovaných kódování#3
iconv -l | sed -E 's!/*$!!'
@pokusit se zjistit kódování textu#4 (3)

3/3 Konverze velikosti písmen

@konvertovat malá písmena na velká (obecně/příklad)#1
sed -E 's/.*/\U&/' [vstupní-soubor]
printf "Žluťoučký kůň\n" | sed -E's/.*/\U&/'⊨ ŽLUŤOUČKÝ KŮŇ
@konvertovat velká písmena na malá (obecně/příklad)#2
sed -E 's/.*/\L&/' [vstupní-soubor]
printf "Žluťoučký kůň\n" | sed -E's/.*/\L&/'⊨ žluťoučký kůň
@konvertovat malá písmena na velká a naopak#3
sed -E 's/./0&/g;s/0([[:lower:]])/1\U\1/g;s/0[[:upper:]]/\L&/g;s/[01](.)/\1/g' [vstupní-soubor]
sed -E 's/(.)/0\1/g;s/0([[:lower:]])/1\U\1/g;s/0([[:upper:]])/1\L\1/g;s/[01](.)/\1/g [vstupní-soubor]

4. Zaklínadla: Práce se záznamy

Důležitá poznámka pro všechna zaklínadla v této sekci: Kde je v zaklínadle volitelný parametr „z“ (resp. „-z“), tento parametr funguje jako přepínač mezi formáty txt a txtz. Při použití formátu txt tento přepínač vynechejte, při použití txtz ho naopak vždy zařaďte.

4/1 Vytvoření a smazání

@vytvořit prázdný soubor (existuje-li, vyprázdnit)#1
> soubor [> další-soubor]
@vytvořit prázdný soubor (existuje-li, jen aktualizovat čas „změněno“)#2
touch soubor
@N-krát zopakovat určitý záznam (txt/txtz)#3 (4)
yes [[--] text-záznamu] | head -n N
printf %s\0 $'text-záznamu' | sed -z ':x;p;b x' | head -zn N

4/2 Filtrace záznamů podle pořadí

@vzít/vynechat N prvních#1
head -[z]n N [soubor]
tail -[z]n +N+1 [soubor]
@vzít/vynechat N posledních#2
tail -[z]n N [soubor]
head -[z]n -N [soubor]
@vzít/vynechat konkrétní záznam#3
sed -[z]n číslo-záznamup [soubor]
sed [-z] číslo-záznamud [soubor]
@vzít/vynechat rozsah záznamů#4
sed -[z]n první-ponechaný,poslední-ponechanýp [soubor]
sed [-z] první-vynechaný,poslední-vynechanýd [soubor]
@vzít pouze liché/sudé záznamy#5
sed -[z]n 'p;n' [soubor]
sed -[z]n 'n;p' [soubor]

4/3 Filtrace záznamů podle obsahu

@vzít/vynechat záznamy odpovídající regulárnímu výrazu#1
egrep [-z] [-x] [parametry] [--] regulární-výraz [soubor]
egrep [-z] -v [-x] [parametry] [--] regulární-výraz [soubor]
@vzít/vynechat záznamy obsahující podřetězec#2 (5)
fgrep [-z] [--] 'podřetězec' [soubor]
fgrep [-z] -v [--] 'podřetězec' [soubor]
@vzít/vynechat záznamy shodné s řetězcem#3
fgrep -[z]x [--] 'řetězec' [soubor]
fgrep -[z]xv [--] 'řetězec' [soubor]
@vzít/vynechat záznamy od prvního vyhovění regulárnímu výrazu#4 (6)
sed -[z]En '/regulární výraz/,$p' [soubor]
sed -[z]E '/regulární výraz/,$d' [soubor]

4/4 Filtrace záznamů podle počtu výskytů

@vybrat ty, které se vysktují pouze jednou#1
LC_ALL=C sort [-z] [soubor] | LC_ALL=C uniq -[z]u
@vybrat ty, které se vyskytují více než jednou (duplicity); vypsat jeden na skupinu/všechny#2
LC_ALL=C sort [-z] [soubor] | LC_ALL=C uniq -[z]d
LC_ALL=C sort [-z] [soubor] | LC_ALL=C uniq -[z]D
@vybrat ty, které se vyskytují N-krát#3
LC_ALL=C sort [-z] [soubor] | LC_ALL=C uniq -[z]c | sed -[z]E 's/^\s*N\s//;t;d'
@seřadit a vypsat počet výskytů (především pro člověka)#4
LC_ALL=C sort [-z] [soubor] | LC_ALL=C uniq -[z]c | sort -[z]n[r]

4/5 Řazení a přeskládání záznamů

@obrátit pořadí (txt/txtz)#1
tac [soubor]
tac -s \\0 [soubor]
@náhodně přeskládat#2
shuf [-z] [soubor]
@seřadit#3
[LC_ALL=C][.UTF-8] sort [-z] [parametry] [soubor]
@seřadit a vyloučit duplicity#4
[LC_ALL=C.UTF-8] sort -[z]u [soubor]
@seskupit k sobě shodné záznamy a tyto skupiny náhodně přeskládat#5
sort -[z]R [soubor]
@seřadit, s výjimkou prvních N záznamů (ty ponechat, jak jsou)#6
[cat soubor |] (sed -[z]u Nq; [LC_ALL=C] sort [-z] [parametry])

4/6 Množinové operace (nad seřazenými záznamy)

@předzpracování textového souboru pro množinové operace (vyžadované!)#1
LC_ALL=C sort -[z]u [soubor]
@množinové sjednocení (or)#2
LC_ALL=C sort -[z]mu první-soubor další-soubor
@množinový průnik dvou souborů (and)#3
LC_ALL=C join [-z] -t "" -j 1 první-soubor druhý-soubor
@množinový rozdíl dvou souborů (and not)#4
LC_ALL=C join [-z] -t "" -j 1 -v 1 hlavní-soubor odečítaný-soubor
@exkluzivní sjednocení dvou souborů (xor)#5
LC_ALL=C join [-z] -t "" -j 1 -v 1 -v 2 soubor1 soubor2
@množinový průnik více souborů (and)#6 (7)
cat první-soubor [| LC_ALL=C join [-z] -t "" -j 1 - další-soubor]

4/7 Ostatní

@počet záznamů (txt/txtz)#1
wc -l < soubor
tr -cd \\0 < soubor | wc -c
@maximální délka záznamu (txt/txtz)#2
tr '\t' x < soubor | wc -L
tr '\0\n\t' '\nxx' < soubor | wc -L
@spojit soubory za sebe#3 (8)
cat soubor
@rozdělit soubor na díly s uvedeným maximálním počtem záznamů (txt/txtz/příklad)#4 (9)
split -d -a počet-číslic -l maximální-počet-záznamů [--additional-suffix='přípona výstupních souborů'] vstupní-soubor "předpona výstupních souborů"
split -d -a počet-číslic -l maximální-počet-záznamů -t \\0 [--additional-suffix='přípona výstupních souborů'] vstupní-soubor "předpona výstupních souborů"
split -d -a 5 -l 100 --additional-suffix='dil.txt' vse.txt "rozdelene-zaznamy/s"
@zapisovat na standardní výstup a současně do souborů#5
[zdroj vstupu |] tee [-a] výstupní-soubor
@obrátit pořadí znaků v každém záznamu (txt/txtz)#6
rev [soubor]
sed -zE 's/[^\n]/)&(/g;s/\n/)xx(/g' [soubor] | tr \\0 \\n | rev | tr \\n \\0 | sed -zE 's/\(xx\)/\n/g;s/\((.)\)/\1/g'
@ke každému záznamu přidat předponu/příponu#7 (10)
sed [-z] $'i\\\npředpona' [soubor] | paste [-z] -d "" - -
sed [-z] $'a\\\npřípona' [soubor] | paste [-z] -d "" - -
@ke každému záznamu přidat předponu i příponu (alternativy)#8 (11)
sed [-z] $'i\\\npředpona\np\nc\\\npřípona' [soubor] | paste [-z] -d "" - - -
sed [-z] 's/.*/předpona&přípona/'
@přidat číslo záznamu pro člověka (txt/txtz)#9
nl [parametry] soubor
gawk 'BEGIN {RS=ORS="\0"; OFS="\t";}{printf("%7d %s\n", NR, $0)}' [--] [soubor]
@přeformátovat text do řádek určité šířky#10 (12)

5. Zaklínadla: Práce se sloupci (TSV, TSVZ)

Důležité poznámka pro všechna zaklínadla v této sekci: Kde je v zaklínadle volitelný parametr „z“ (resp. „-z“), tento parametr funguje jako přepínač mezi formáty tsv a tsvz. Při použití formátu tsv tento přepínač vynechejte, při použití tsvz ho naopak vždy zařaďte.

5/1 Vybrat/spojit sloupce

@vzít/vynechat určité sloupce#1 (13)
cut [-z] [-d oddělovač] -f specifikace,sloupců [soubor]
cut --complement [-z] [-d oddělovač] -f specifikace,sloupců [soubor]
@vzít určité sloupce (bez omezení)#2 (14)
join [-z] --nocheck-order -j 1 -a 2 -t $'\t' -o 2.číslo-prvního-sloupce[,2.číslo-dalšího-sloupce] /dev/null soubor
@spojit sloupce ze dvou či více souborů podle čísla záznamu#3
paste [-z] [-d oddělovač] soubor1 soubor2 [další-soubor]
@spojit sloupce ze dvou souborů podle společného sloupce (komplikované)#4 (15)
[LC_ALL=C] join [-z] [další parametry] -t $'\t' -1 číslo-sloupce-v-prvním-souboru -2 číslo-sloupce-v-druhém-souboru [-a 1] [-a 2] [-o definice-výstupu] soubor1 soubor2

5/2 Filtrace podle obsahu sloupců

Pro tsvz uveďte část „;RS=ORS="\0";“.

@vzít/vynechat záznamy, kde N-tý sloupec odpovídá regulárnímu výrazu#1
gawk 'BEGIN {FS=OFS="\t"[;RS=ORS="\0";]} $N ~ /regulární výraz/' [soubor]
gawk 'BEGIN {FS=OFS="\t"[;RS=ORS="\0";]} $N !~ /regulární výraz/' [soubor]
@vzít/vynechat záznamy, kde N-tý sloupec obsahuje podřetězec#2
gawk 'BEGIN {FS=OFS="\t"[;RS=ORS="\0";]} index($N, "podřetězec")' [soubor]
gawk 'BEGIN {FS=OFS="\t"[;RS=ORS="\0";]} !index($N, "podřetězec")' [soubor]
@vzít/vynechat záznamy, kde N-tý sloupec je řetězec#3
gawk 'BEGIN {FS=OFS="\t"[;RS=ORS="\0";]} $N == "podřetězec"' [soubor]
gawk 'BEGIN {FS=OFS="\t"[;RS=ORS="\0";]} $N != "podřetězec"' [soubor]

5/3 Řazení záznamů podle obsahu sloupců

@seřadit podle N-tého sloupce#1
[LC_ALL=C.UTF-8] sort [-z] -t $'\t' -k N,N[druh-a-příznaky-řazení] [soubor]
@seřadit podle sloupců M až N (včetně)#2
[LC_ALL=C.UTF-8] sort [-z] -t $'\t' -k M,N[druh-a-příznaky-řazení] [soubor]
@seřadit podle více kritérií#3
[LC_ALL=C.UTF-8] sort [-z] [-s] -t $'\t' -k jedno-kritérium [-k další-kritérium] [soubor]
@příklad: seřadit vzestupně podle číselné hodnoty 7. sloupce a pak sestupně podle 3. sloupce, bez ohledu na velikost písmen#4
sort [-z] -t $'\t' -k 7,7n -k 3,3ri [soubor]

5/4 Ostatní

Pro formát tsvz použijte „RS="\0";“, pro tsv jej vynechejte.

@počet sloupců prvního záznamu#1
head [-z] soubor | tr -cd \\t | wc -c
@maximální počet sloupců (tsv/tsvz)#2
gawk 'BEGIN {FS="\t"; [RS="\0";] r=0;} NR == 1 || NF > r {r = NF} END {print r}' [soubor]
@minimální počet sloupců#3 (16)
gawk 'BEGIN {FS="\t"; [RS="\0";] r=0;} NR == 1 || NF < r {r = NF} END {print r}' [soubor]
@naformátovat záznamy jako tabulku s pevnou šířkou sloupců (tsv/tsvz)#4
column -nt[e] -s $'\t' [soubor]
[cat soubor |] tr '\0\n' '\n ' | column -n[e]t -s $'\t' | tr \\n \\0
@vložit sloupec s číslem záznamu před první sloupec#5 (17)
gawk 'BEGIN { [RS = ORS = "\0";] OFS = "\t";} {print NR, $0}' [soubor]
@vložit sloupec s číslem záznamu před N-tý sloupec, kde N není 1#6
gawk [-v 'RS=\0'] '{print gensub(/\t/, "\t" NR "\t", N - 1);}' [soubor]

6. Zaklínadla: Práce se znaky a podřetězci

6/1 Náhrada

@náhrada podřetězce podle regulárního výrazu#1 (18)
sed -[z]E 's/regulární výraz/řetězec náhrady/[g]' [soubor]
@transliterace (náhrada znaků podle tabulky)(obecně/příklad)#2 (19)
sed -[z]E 'y/znak-původní/znak-náhradní/' [soubor]
sed -E 'y/A\/B\\C/a|b|c/' test.txt

6/2 Vybrat/spojit sloupce

@vzít určité sloupce (obecně/příklad)#1 (20)
gawk 'BEGIN{FS=OFS=""}{print $číslo-sloupce[,další-číslo-sloupce]}' [soubor]
gawk 'BEGIN{FS=OFS=""}{print $3, $5, $4, $7}' <<<'AŽČŠVŘů'⊨ ČVŠů
@vynechat určité sloupce#2
colrm první-vynechaný [poslední-vynechaný] [< soubor]
@vynechat prvních/posledních deset znaků každé řádky#3
colrm 1 10
sed -E 's/.{,10}$//'

6/3 Filtrace podle obsahu sloupců

@vzít/vynechat záznamy, jejichž podřetězec na indexech M až N odpovídá regulárnímu výrazu#1
gawk '[BEGIN {RS=ORS="\0"}] substr($0, M, N - M + 1) ~ /regulární výraz/' [soubor]
gawk '[BEGIN {RS=ORS="\0"}] substr($0, M, N - M + 1) !~ /regulární výraz/' [soubor]
@vzít/vynechat záznamy, jejichž podřetězec na indexech M až N obsahuje podřetězec#2
gawk '[BEGIN {RS=ORS="\0"}] index(substr($0, M, N - M + 1), "podřetězec")' [soubor]
gawk '[BEGIN {RS=ORS="\0"}] !index(substr($0, M, N - M + 1), "podřetězec")' [soubor]
@vzít/vynechat záznamy, jejichž podřetězec na indexech M až N je daný řetězec#3
gawk '[BEGIN {RS=ORS="\0"}] substr($0, M, N - M + 1) == "řetězec"' [soubor]
gawk '[BEGIN {RS=ORS="\0"}] substr($0, M, N - M + 1) != "řetězec"' [soubor]

6/4 Řazení

@řadit podle znaků na indexech M až N (včetně)#1
[LC_ALL=C.UTF-8] sort [další parametry] -k 1.M,1.Nparametry-řazení [soubor]

7. Zaklínadla: Záplatování

@vytvořit záplatu adresáře#1 (21)
diff -Nar -U 3 starý-adresář nový-adresář > soubor.pdiff || test $? -eq 1
@aplikovat záplatu adresáře#2
patch -N -p 1 -d adresář < soubor.pdiff
@vytvořit záplatu souboru#3
LC_ALL=C TZ=UTC diff -Na -U 3 starý-soubor nový-soubor > soubor.pdiff || test $? -eq 1
@aplikovat záplatu souboru#4
patch -NZ[t] cílový-soubor soubor.pdiff

8. Parametry příkazů

8/1 cut

cut parametry [soubor]
☐ -d oddělovačNastaví oddělovač sloupců pro parametr -f; výchozí je "\t", což znamená tabulátor. Používejte pouze znaky ASCII.
○ -f sloupce ○ -b bajtyDefinuje množinu sloupců či bajtů každého záznamu, které mají být propuštěny. Pozor, pořadí ani duplicity nemají vliv na výstup! Příklad specifikace: „7,13-15,-3,20-“
☐ --complementNeguje definovanou množinu – vybrané sloupce či bajty vypustí a vezme zbytek.
☐ -zUkončovač záznamu je \0 místo \n.

8/2 join

[LC_ALL=C.UTF-8] join parametry soubor1 soubor2
○ -1 sloupec -2 sloupec ○ -j sloupec-pro-obaUrčuje společný sloupec ve vstupních souborech.
☐ -t znakDefinuje oddělovač sloupců. Prázdný argument značí, že se soubory na sloupce nedělí.
○ -a 1-nebo-2 ○ -v 1-nebo-2Dovolí vypsání nespárovaných záznamů ze souboru 1 nebo 2. Varianta „-v“ navíc potlačí vypsání spárovaných záznamů.
☐ -o formátDefinuje pořadí sloupců na výstupu. Jednotlivé specifikace mohou mít tvar „0“ (společný sloupec), „1.číslo“ pro sloupec prvního souboru nebo „2.číslo“ pro sloupec druhého souboru. Specifikace se oddělují čárkami nebo mezerami. Příklad specifikace: „0,1.1,1.2,2.1,2.2,0“.
☐ -zUkončovač záznamu je \0 místo \n.
○ --check-order ○ --nocheck-orderZapne, resp. vypne kontrolu uspořádání vstupního souboru.

8/3 paste

paste [parametry] [soubor]
☐ -d oddělovačeDefinuje znaky vkládané v místech spojení záznamů. Je-li předaný řetězec prázdný, použijí se prázdné řetězce, jinak se budou cyklicky používat jednotlivé znaky ze zadaného řetězce.
☐ -zUkončovač záznamu je \0 místo \n.
☐ -sUkončovače záznamu kromě posledního interpretuje jako oddělovače sloupců, tím pádem spojí všechny záznamy do jednoho.

8/4 sed

sed [parametry-kromě-e-či-f] skript-sedu [soubor]
sed parametry-včetně-e-či-f [soubor]
☐ -EPoužije rozšířené regulární výrazy místo základních (doporučuji vždy, když skript obsahuje regulární výraz).
☐ -nPotlačí automatické vypsání „pracovní paměti“ po každém cyklu skriptu.
☐ -zUkončovač záznamu je \0 místo \n.
○ -e skript-sedu ○ -f souborNačte skript z parametru, resp. ze souboru; oba parametry lze kombinovat či použít opakovaně.
☐ -uNačítá jen nezbytný počet bajtů a vypisuje na výstup co nejdřív.

8/5 sort

[LC_ALL=C.UTF-8] sort [parametry] [soubor]
☐ -uPo seřazení vyloučí duplicity (z každé skupiny duplicitních řádků ponechá pouze jeden).
○ -c ○ -CNeřadí; jen zkontroluje, zda je vstup seřazený. Varianta „-c“ navíc vypíše první chybně seřazený řádek.
☐ -k definice-řadicího-klíčedruh-a-příznaky-řazeníDefinuje řadicí klíč, podle kterého se má řadit. Podrobněji – viz manuálová stránka příkazu sort.
☐ -t oddělovačDefinuje oddělovač polí při řazení podle klíčů.
☐ -mMísto řazení pouze slučuje již seřazené soubory do jednoho.
☐ -sStabilní řazení. Zachová relativní pořadí řádků, jejichž všechny řadicí klíče se rovnají.
○ -druh-řazeníPřepne na jiný druh řazení než obyčejné řetězcové.
☐ -příznak-řazeníNastaví příslušný příznak ovlivňující řazení.

Druhy řazení jsou: g, h, M, n, R, V. Za zmínku z nich stojí jen „n“ – řazení podle číselné hodnoty (včetně případných desetinných míst) a „h“ – totéž, ale s rozpoznáváním přípon K (kilo), M (mega) atd.

Příznaky řazení jsou tyto:

rŘadit sestupně (normálně se řadí vzestupně).
fNerozlišovat velká a malá písmena.
d„Řazení jako ve slovníku“ – zohledňovat jen písmena, čísla a bílé znaky.
bIgnorovat bílé znaky na začátku klíče (při řazení podle číselné hodnoty se ignorují vždy).
iIgnorovat netisknutelné znaky.

9. Instalace na Ubuntu

Všechny použité nástroje jsou základními součástmi Ubuntu, s výjimkou gawk, které, pokud je potřebujete, je nutno doinstalovat:

sudo apt-get install gawk

10. Tipy a zkušenosti

  • Nastavení „LC_ALL=C“ zapíná řazení po bajtech podle jejich číselné hodnoty. Je rychlé, spolehlivé a dokonale přenositelné, nejde však o řazení pro člověka.
  • Pozor, „sort -k 2“ znamená řadit podle sloupců 2, 3, 4 atd. až do konce; řazení podle sloupce číslo 2 je „sort -k 2,2“!
  • Řazení podle klíčů může být pro začátečníka záludné. Doporučuji zvolený klíč nejprve otestovat na krátkém vstupním souboru s parametrem „--debug“.

11. Další zdroje informací

Nejlepším zdrojem podrobnějších informací o jednotlivých použitých příkazech (s výjimkou příkazu „column“) jsou jejich manuálové stránky.

12. Zákulisí kapitoly

V této verzi kapitoly chybí:

  • zpracování formátů CSV a PSV

Tato kapitola záměrně nepokrývá:

  • zpracování textových formátů se složitější strukturou jako např. JSON či XML
1 Užitečná kódování: ISO8859-2, WINDOWS-1250, UTF-16, UTF-16BE, UTF-16LE, UTF-8, CP852 (MS-DOS), MAC-CENTRALEUROPE.
2 Poznámka: tato konverze je ztrátová, a tudíž prakticky jednosměrná.
3 Tip: přibližně může pomoci příkaz „file“ nebo autodetekce kódování při otevření textového souboru ve Firefoxu.
4 Výchozí hodnota textu záznamu je „y“.
5 Poznámka: V hledaném podřetězci se nesmí vyskytovat znak \n, a to ani u formátu txtz, protože fgrep tento znak používá k oddělení více různých hledaných podřetězců. Pokud váš podřetězec tento znak obsahuje, existuje několik řešení, nejjednodušším je pomocí příkazu „tr“ na vstupu i výstupu příkazu fgrep prohodit znak \n s jiným ASCII znakem, který se v hledaném podřetězci nevyskytuje.
6 Znaky „/“ v regulárním výrazu je nutno odzvláštnit zpětným lomítkem (popř. GNU sed umožňuje použít jiný oddělovač regulárního výrazu).
7 Tip: nejlepšího výkonu této varianty dosáhnete tak, že začnete od nejmenšího vstupního souboru.
8 Standardní vstup můžete mezi soubory vřadit parametrem „-“ místo názvu souboru. Neprázdné soubory musejí být řádně ukončeny ukončovačem záznamu, jinak se poslední záznam spojí s prvním záznamem následujícího souboru.
9 Přípona výstupních souborů nesmí obsahovat oddělovač adresářů „/“. Číslování výstupních souborů začíná od nuly; jinou hodnotu lze nastavit, když místo parametru -d použijete parametr --numeric-suffixes=číslo. Uvedený příklad rozdělí soubor „vse.txt“ po sto řádcích na soubory „rozdelene-zaznamy/s00000dil.txt“, „rozdelene-zaznamy/s00001dil.txt“ atd.
10 Příkaz „sed“ vyžaduje v příponě i předponě další úroveň odzvláštnění znaků „\“ a „\n“. Proto v uvedeném případě zadávejte zpětné lomítko jako „\\\\“ a konec řádky jako „\\\n“. Konec řádky se navíc může vyskytnout pouze při použití formátu txtz, u formátu txt pravděpodobně nebude fungovat správně.
11 Uvedené varianty se liší požadavky na odzvláštnění v příponě: v první variantě sed požaduje dodatečné odzvláštění znaků „\“ a (případně) konce řádku; v druhé variantě požaduje sed odzvláštnění znaků „\“, „/“ a „&“.
12 Běžně se k tomu používá příkaz „fmt“, ale ten nerespektuje vícebajtové znaky, takže pro texty v UTF-8 funguje nekorektně.
13 Specifikace sloupců specifikuje množinu (tzn. ne výčet) sloupců. Má tvar jednotlivých čísel oddělených čárkami, např. „7,3,2,5,2“ vypíše sloupce 2, 3, 5 a 7. Místo jednotlivého čísla lze zadat rozsah ve tvaru „číslo-číslo“, „číslo-“ nebo „-číslo“, který se rozvine na všechny odpovídající sloupce, takže např. specifikace „7,3-5,-4“ odpovídá sloupcům 1, 2, 3, 4, 5 a 7.
14 Pro čtení ze standarního vstupu zadejte místo souboru „-“.
15 Chování příkazu „join“ je smysluplné, ale poměrně komplikované. Před použitím tohoto zaklínadla prosím nastudujte manuálovou stránku příkazu join!
16 Poznámka: prázdný řádek se počítá jako 0 sloupců, proto pokud ho vstup obsahuje, výsledek bude 0.
17 Poznámka: zadáte-li víc souborů, počítadlo záznamů se nebude restartovat na začátku každého z nich.
18 Pro podrobnější popis syntaxe vyhledejte kapitolu Sed!
19 Počet „původních“ a „náhradních“ znaků musí přesně odpovídat. Znaky „/“ a „\“ je v obou výčtech nutno odzvláštnit dalším zpětným lomítkem. Na místo znaku můžete použít i sekvenci „\0“, „\n“ apod. „Náhradní znaky“ se smí opakovat, „původní“ ne.
20 Pro složitější případy je v GNU awk funkce „substr()“ nebo zvláštní režim pro zpracování souborů s pevnou šířkou sloupců.
21 Aby záplata fungovala, označení starého a nového adresáře nesmějí obsahovat žádná lomítka, musejí to být jen holá jména podadresářů aktuálního adresáře.
Líbí se vám tento projekt a chcete, aby byl ještě lepší? Můžete mi s tím pomoci. Zmiňte se o něm technicky zdatným přátelům, opravte překlepy a nahlašte nefunkční zaklínadla, aby mohla být opravena; poskytněte mi zpětnou vazbu nebo se zapojte do vývoje nových kapitol. Další informace na GitHubu v dokumentu Jak se zapojit.
[BY-SA]

Veškerý obsah této stránky (text, obrázky, zdrojový kód) je možno upravovat a šířit pod podmínkami licence Creative Commons Attribution-ShareAlike 4.0 International. Upozorňuji, že uvedená licence vyžaduje uvedení seznamu autorů, licence a zdroje a poskytnutí stejné či kompatibilní licence k provedeným změnám, jsou-li nějaké. Příslušné údaje jsou dostupné na stránce „Přehled autorů“. Šíření obsahu bez těchto údajů nebo šíření upravené verze bez poskytnutí adekvátní licence k provedeným úpravám je pravděpodobně porušení licenčních podmínek a může být postihováno. Poskytování zdrojového kódu při šíření není touto licencí vyžadováno.

Pro nové verze, další informace, aktuální zdrojový kód a možnost se zapojit do projektu „Linux: Kniha kouzel“ navštivte jeho repozitář na GitHubu.