Nauč se Python > Kurzy > Linuxová administrace > Bash II > Hledání: grep a find

Hledání

Přesuň se do adresáře data-shell/writing, kde se nachází soubor haiku.txt

$ cat haiku.txt 
The Tao that is seen
Is not the true Tao, until
You bring fresh toner.

With searching comes loss
and the presence of absence:
"My Thesis" not found.

Yesterday it worked
Today it is not working
Software is like that.

(Jsou to básničky ze soutěže časopisu Salon.)

grep

Náš úkol je podívat se na řádky, kde se nachází slovo not. Existuje program grep, kterému předáš hledané slovo a soubor(y) k prohledání – a on řádky s daným slovem vypíše.

Následující příkaz tedy hledá v souboru haiku.txt řetězec not a vypíše každý řádek s tímto řetězcem:

$ grep not haiku.txt 
Is not the true Tao, until
"My Thesis" not found.
Today it is not working

Příkaz grep má spoustu zajímavých přepínačů, například:

  • -i: Nezáleží na velikosti písmen (case insensitive).
  • -n: Vypíše čísla řádků.
  • -w: Hledá jen celá slova.
  • -F: Hledá přesně zadaný řetězec (viz níže).

Takhle můžeš najít všechny řádky se slovem the nebo The:

$ grep -i the haiku.txt 
The Tao that is seen
Is not the true Tao, until
and the presence of absence:
"My Thesis" not found.

Jejda, tam je ale něco navíc! Jak příkazem odstraníš z výpisu řádek se slovem Thesis?

$ grep -iw the haiku.txt 
The Tao that is seen
Is not the true Tao, until
and the presence of absence:

grep je velice užitečný program. Pokud pracuješ s Bashem, brzy se z něj stane tvůj nejlepší kamarád. Pozor ale na to, co grep bere jako hledaný řetězec: je to totiž regulární výraz (angl. regular expression, regex). Pokud hledáš jen písmenka, nenarazíš na problém, ale u znaků jako tečky, hvězdičky, otazníky apod. může být výstup jiný než očekáváš.

Zkus několik příkazů:

$ grep -i the.i haiku.txt 
$ grep -i '.*' haiku.txt
$ grep -iw '.....' haiku.txt

Regulární výrazy jsou velice užitečné, ale taky jsou nad rámec tohoto kurzu (nebo aspoň této lekce). Zatím si tedy zapamatuj, že speciální funkce znaků můžeš vypnout pomocí přepínače -F (aby je nezpracoval grep) a uzavřením do jednoduchých uvozovek (aby je nezpracoval Bash).

find

Příkaz find je další užitečný hledací příkaz.

$ find . -name '*.txt'
./haiku.txt
./data/LittleWomen.txt
./data/two.txt
./data/one.txt

Příklad výše hledá v aktuálním adresáři (.) a všech podadresářích soubory, které odpovídají masce *.txt.

Proč je '*.txt' v uvozovkách? Vzpomeň si, že znak * zpracovává samotný Bash: kdybys *.txt zadala bez uvozovek, find by dostal jako argumenty všechny soubory *.txt z aktuálního adresáře. Uvozovky říkají Bashi, aby příkazu find předal opravdu *.txt. find tak může odpovídající soubory hledat sám – i v podadresářích.

Příkaz find má kromě -name spoustu jiných přepínačů. Až je budeš potřebovat, najdeš je v manuálové stránce.

Podobného výsledku jako výše (ale bez jména adresáře) dosáhneš když zadáš:

$ ls --recursive | grep txt
haiku.txt
LittleWomen.txt
one.txt
two.txt

I bez jména adresáře se takový výstup občas hodí – třeba když chceš spočítat, kolik těch souborů je:

$ ls --recursive | grep txt | wc -l
4

Toto je stránka lekce z kurzu, který probíhá nebo proběhl naživo s instruktorem.