Hrátky z řádky: porovnání souborů a číselné řady

4. 8. 2016
Doba čtení: 4 minuty

Sdílet

Další díl občasného zpravodajství z příkazové řádky. Dnes se podíváme na několik programů pro porovnávání souborů, jejich spojování a vygenerujeme si i nějakou číselnou řadu.

Porovnávání souborů

Když se řekne porovnávání souborů (budeme pracovat převážně s textovými), mnoho uživatelů asi hned napadne program diff. Je to šikovný program, ale každému se nemusí líbit jeho výstup. A občas to může být zbytečně velký kanon na vrabce. Ukážeme si několik méně známých programů, které dělají stejnou nebo podobnou práci.

Napřed si připravíme dva testovací soubory:

$ cat prvni.txt
ahoj,
ja jsem prvni soubor a jsem
jediny a originalni
$ cat druhy.txt
ahoj,
ja jsem druhy soubor a jsem
skoro jediny a originalni

Cmp

Cmp porovnává dva soubory bajt po bajtu a oznámí první rozdíl. Pokud přidáme parametr -b, řekne i o který znak se jedná.

$ cmp prvni.txt druhy.txt
prvni.txt druhy.txt se liší: bajt 15, řádek 2
$ cmp -b prvni.txt druhy.txt
prvni.txt druhy.txt se liší: bajt 15, řádek 2 je 160 p 144 d

Sdiff

Program sdiff má více ukecaný a přehlednější výstup. Každý ze souborů zobrazuje na jedné polovině obrazovky a zvýrazňuje rozdíly. Soubor prvni.txt si rozšíříme o jeden řádek:

echo koncim >> prvni.txt

Parametr -s říká, že se nebudou vypisovat shodné řádky, dalšími parametry je možné nastavit ignorování více mezer, bílé znaky na konci řádků apod.

$ sdiff -s prvni.txt druhy.txt
ja jsem prvni soubor a jsem                                   | ja jsem druhy soubor a jsem
jediny a originalni                                           | skoro jediny a originalni
                                  > koncim

Znak | značí řádek, kde je rozdíl, <> pak značí řádek chybějící v jednom nebo druhém souboru. Sdiff toho umí ale mnohem více, třeba interaktivní spojování souborů. Koukněte do manuálu.

Comm

Dalším porovnávačem je program comm. Porovnává řádek po řádku a záleží na pořadí řádků v souborech. Zobrazení výstupu řeší jinak, a to pomocí tabelátoru.

  • bez – řádek je v pouze v prvním souboru
  • 1 tab – řádek je v druhém souboru
  • 2 taby – řádek je shodný v obou souborech
$ comm prvni.txt druhy.txt
                ahoj,
        ja jsem druhy soubor a jsem
ja jsem prvni soubor a jsem
jediny a originalni
koncim
        skoro jediny a originalni

Diff

Příkaz diff je o dost mocnější. Parametrem -i říkáme, aby nerozlišoval velká a malá písmena, pro textové soubory se mohou hodit i parametry týkající se bílých znaků na koncích řádků ( -Z), množství mezer mezi slovy ( -b)…

Více se o něm dozvíte třeba v blogu Petra Krčmáře.

Číselné řady s Jot

Teď trochu něco jiného. Začnu programem jot. Nazval bych jej generátorem číselných a znakových řad. Nemusí se jednat jen o sekvenční data, jot umí generovat i pomocí náhody.

Základní parametry jsou čtyři – počet hodnot, první, poslední a krok. Pokud chceme nějaký vynechat, zadáváme místo něj pomlčku.

V některých případech nemusíme ani to. Sílu tohoto programu si nejlépe ukážeme na pár příkladech.

Začneme s čísly:

$ jot 4
1
2
3
4

Teď sestupně. Všimněte si, že se k číslu –9 vůbec nedostaneme, protože dříve nastane počet opakování (8). Pokud by byl počet opakování vyšší, výstup se zastaví u hodnoty –9.

$ jot -p1 8 0 -9 -0.5
0.0
-0.5
-1.0
-1.5
-2.0
-2.5
-3.0
-3.5

Parametr -p není nutné zapisovat ani takto, zkuste třeba následující příklad. Krok se automaticky dopočítá a počet desetinných míst se taky upraví:

$ jot  5 0 10.00

Občas se taková věc může hodit třeba v kombinaci s for:

for hodnota in `jot 4 100`
do
    echo $hodnota
done

A jdeme na znaky. Neznáte pozici písmene H v ascii tabulce?

$ jot 1 H
72

Můžeme převádět i obráceně:

$ jot -c 1 72
H

Je možné pracovat i s řetězci

$ jot -w ahoj_%c 26 a
ahoj_a
ahoj_b
ahoj_c
ahoj_d
ahoj_e
ahoj_f
…

Generování jednoduchých hesel: -s říká, jaký oddělovač použít, -r je náhoda a -c říká, že jde o znaky. Pak už jen počet opakování, minimální a maximální hodnota.

$ jot -s "" -r -c 8 a z
hdwimmst

Expand a unexpand

Tato utilita nám v zadaném souboru nahradí tabulátory mezerami nebo obráceně.

$ expand pokus_s_taby.txt > pokus_s_mezerami.txt

Obráceně to dělá utilita unxepand, nezapomeňte na parametr  -a.

$ unexpand -a pokus_s_mezerami.txt > pokus_s_taby.txt

Paste

Paste spojuje soubory, vezme první řádky všech souborů a dá je na první řádek, stejně tak s ostatními.

Vytvoříme si dva ukázkové soubory

$ cat prvni.txt
ahoj,
ja jsem prvni soubor,
kde jsou
4 radky

$ cat druhy.txt
nazdar,
ja jsem tvuj
druhy kolega
a stejne dlouhy

$ paste prvni.txt druhy.txt
ahoj,   nazdar,
ja jsem prvni soubor,   ja jsem tvuj
kde jsou        druhy kolega
4 radky a stejne dlouhy

Paste toho umí taky ještě víc. Když chcete třeba nahradit konce řádků znakem tab

$ paste -s prvni.txt
ahoj,   ja jsem prvni soubor,   kde jsou        4 radky

Podobnou funkci mí i příkaz lam. Ten se třeba v základní instalaci Ubuntu nevyskytuje, ale ve FreeBSD je.

bitcoin_skoleni

Vynechání sloupců s colrm

Nedávno jsem v diskuzi narazil na extrahování některých sloupců z výpisu. Většina uživatelů na to využívá třeba awk. Existuje ale i utilita colrm, která je velmi jednoduchá a dáváte jí pouze jeden nebo dva parametry – od a do kterého sloupce má vynechávat.

$ ls -al | colrm 10 33
…
drwx----- čen 14  2013 .adobe
-rw------ srp  2 22:38 .bash_history
-rw-r--r- čen 14  2013 .bash_logout
-rw-r--r- čen 14  2013 .bashrc
…

Tak to je pro dnešek vše. Hrátky z řádky asi začnou znovu a nepravidelně vycházet. Máte nějaké tipy? Prosím, podělte se v diskuzi.

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.