Index 🏠 || 🔝 Nahoru


Publikováno:

Aktualizováno

Série »Linux shell«

Kategorie:

PSKáčko

Tagy:

Tohle není učebnice — je to kuchařka. Máte problém, hledáte recept. Ke každé úloze jsou ukázány jak klasické unixové nástroje, které najdete na každém systému, tak i moderní alternativy, které si možná budete muset doinstalovat, ale práci vám výrazně zpříjemní.


… chci se podívat, co je v souboru

Klasika: cat, less, head, tail

Nejjednodušší je cat — celý soubor vypluje na terminál:

1
$ cat soubor.txt

Na velké soubory je lepší interaktivní prohlížeč less. Pohybujete se šipkami, Space skočí o stránku dopředu, q ukončí, / spustí hledání:

1
$ less soubor.txt

Jen začátek nebo konec souboru:

1
2
$ head -20 soubor.txt
$ tail -20 soubor.txt

Skvělé pro sledování průběžně rostoucího logu (přidává se na konec):

1
$ tail -f /var/log/syslog

Moderní: bat

Program bat je cat na steroidech: zvýrazní syntaxi, zobrazí čísla řádků a ukáže i změny oproti Gitu. Automaticky spustí stránkovač, pokud se soubor nevejde na obrazovku:

1
2
$ bat soubor.py
$ bat --style=plain soubor.txt   # bez ozdůbek, jen zvýraznění

… hledám soubor podle jména

Klasika: find

find prochází adresářový strom a hledá soubory splňující zadaná kritéria:

1
2
3
4
$ find . -name "*.txt"
$ find . -name "*.txt" -mtime -7         # změněné za posledních 7 dní
$ find . -type d -name "build"           # hledá adresáře jménem build
$ find . -size +10M                      # soubory větší než 10 MB

Výsledky lze rovnou předat dalšímu příkazu:

1
$ find . -name "*.log" -exec rm {} \;

Moderní: fd

fd je výrazně rychlejší, výchozí chování je rozumnější (respektuje .gitignore, ignoruje skryté soubory), výstup je barevný a syntaxe příjemnější:

1
2
3
4
$ fd '.txt'                   # ekvivalent find . -name '*.txt'
$ fd -e txt                   # hledání podle přípony
$ fd -t d build               # jen adresáře jménem build
$ fd --changed-within 7d      # změněné za posledních 7 dní

… hledám soubor podle jeho obsahu

Klasika: grep

grep prohledá soubory a vypíše řádky odpovídající vzoru:

1
2
3
4
$ grep "hledany text" soubor.txt
$ grep -r "pattern" .               # rekurzivně v celém adresáři
$ grep -rn "pattern" --include="*.py"  # jen .py soubory, s čísly řádků
$ grep -rl "pattern" .              # vypíše jen jména souborů, ne shody

Moderní: rg (ripgrep)

rg je několikanásobně rychlejší než grep, automaticky respektuje .gitignore, výstup je přehledně barevný a výchozí chování dává smysl:

1
2
3
4
$ rg "pattern"
$ rg "pattern" --type py          # jen Python soubory
$ rg -l "pattern"                 # jen jména souborů
$ rg -C 3 "pattern"               # 3 řádky kontextu kolem shody

… hledám, která složka zabírá nejvíc místa

Klasika: du + sort

du (disk usage) změří velikost adresářů. Samotný výstup je ale chaotický — teprve v kombinaci se sort to dává smysl:

1
2
3
$ du -sh *                         # přehled velikostí v aktuálním adresáři
$ du -sh * | sort -h               # seřazené od nejmenšího
$ du -sh * | sort -rh | head -10   # 10 největších

Moderní: dua, dust, ncdu

Interaktivní TUI nástroje ukáží stromovou strukturu a umožňují procházet adresáře podobně jako správce souborů.

ncdu je nejrozšířenější:

1
$ ncdu

dust dá okamžitý přehled bez interaktivity — výstup je graficky přehledný:

1
2
$ dust
$ dust -d 2        # maximální hloubka 2 úrovně

… chci interaktivně vybrat soubor nebo příkaz

fzf — fuzzy finder

fzf je interaktivní fuzzy vyhledávač pro terminál. Dostane na vstup seznam položek a umožní vám rychle vybrat jednu (nebo více) pomocí napsání části hledaného výrazu. Hodí se všude:

Vybrat soubor a otevřít ho v editoru:

1
$ vim $(fzf)

Vyhledat v historii příkazů (integruje se i do Ctrl+R):

1
$ history | fzf

Přejít do adresáře:

1
$ cd $(find . -type d | fzf)

Kombinace s fd:

1
$ vim $(fd -e py | fzf)

Po integraci fzf do shellu získáte:

Ctrl+R
fuzzy vyhledávání v historii příkazů
Ctrl+T
fuzzy výběr souborů přímo do příkazového řádku
Alt+C
interaktivní přechod do podadresáře

… chci seřadit a najít nejčastější položky

sort a uniq

Klasická kombinace pro analýzu textového výstupu:

1
2
3
$ sort soubor.txt                  # abecedně
$ sort -n soubor.txt               # číselně
$ sort -rh soubor.txt              # reverzně, "human" velikosti (1K, 2M)

uniq odstraní nebo spočítá duplicitní řádky (vstup musí být seřazený):

1
2
$ sort soubor.txt | uniq            # odstraní duplicity
$ sort soubor.txt | uniq -c         # před každý řádek přidá počet výskytů

Zlatá kombinace — zjistěte, co se v logu opakuje nejčastěji:

1
$ cat access.log | sort | uniq -c | sort -rn | head -20

… chci zobrazit strukturu adresáře

Klasika: tree

1
2
3
$ tree
$ tree -L 2              # maximálně 2 úrovně
$ tree -a                # včetně skrytých souborů

Moderní: eza

eza je moderní náhrada za ls s barvami, ikonami a spoustou přehledných voleb. Stromový výpis zvládne taky:

1
2
3
4
$ eza -la                          # dlouhý formát, vše
$ eza --tree                       # stromová struktura
$ eza --tree --level=2             # maximálně 2 úrovně
$ eza -la --git                    # zobrazí i stav v Gitu

… chci přejmenovat hromadu souborů najednou

rename

Příkaz rename provede přejmenování podle regulárního výrazu (syntaxe se liší podle verze — Perlová varianta):

1
2
3
$ rename 's/old/new/' *.txt           # v názvech nahradí old → new
$ rename 's/\.JPG$/.jpg/' *.JPG       # přípona z velkých na malá
$ rename -n 's/foto/photo/' *.jpg     # -n = dry run, jen ukáže co by udělal

Shell cyklus

Bez extra nástrojů zvládne přejmenování i prostý for cyklus:

1
2
$ for f in *.JPG; do mv "$f" "${f%.JPG}.jpg"; done
$ for f in foto_*.jpg; do mv "$f" "${f/foto_/photo_}"; done

… chci sledovat průběh dlouhé operace

pv — pipe viewer

pv se vloží do roury a ukáže průběh (množství dat, rychlost, odhadovaný čas):

1
2
$ pv velky_soubor.iso > /dev/null          # jen sleduje čtení
$ pv velky_soubor.tar.gz | tar xz          # rozbalování s průběhem

Lze použít i pro kopírování:

1
$ pv zdroj.dat > cil.dat

rsync --progress

rsync ukáže průběh přenosu a přidává možnost pokračovat po přerušení:

1
$ rsync -av --progress zdroj/ cil/

… chci porovnat dva soubory

Klasika: diff

diff ukáže rozdíly řádek po řádku:

1
2
$ diff soubor1.txt soubor2.txt
$ diff -u soubor1.txt soubor2.txt    # unifikovaný formát (jako git diff)

Moderní: delta

delta je vizuálně výrazně přehlednější — zvýrazní syntaxi, zobrazí čísla řádků, zarovná změny do sloupců. Použije se jako pager pro diff nebo pro git diff:

1
$ diff -u soubor1.py soubor2.py | delta

Po nastavení v ~/.gitconfig automaticky vylepší i výstup git diff a git log.


… chci pracovat s textem v rouře

Pár oblíbených jednolinkovek, které ukazují sílu unixové filozofie:

Počet souborů v adresáři:

1
$ ls | wc -l

Sečíst čísla ze souboru (každé číslo na jednom řádku):

1
$ awk '{s+=$1} END {print s}' cisla.txt

Vypsat unikátní IP adresy z logu (třetí sloupec):

1
$ awk '{print $3}' access.log | sort -u

Najít 5 nejpoužívanějších příkazů z historie:

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

Vytvořit seznam souborů a jejich velikostí seřazený od největšího:

1
$ ls -lh | sort -k5 -rh | head -10

Kde hledat moderní nástroje

Většinu moderních nástrojů najdete v repozitářích vaší distribuce nebo je lze stáhnout jako statické binárky z jejich GitHub stránek.

Na Debianu/Ubuntu:

1
$ apt install bat fd-find ripgrep fzf ncdu pv tree eza delta

Pozor: bat se na Debianu jmenuje batcat a fd se jmenuje fdfind (kvůli jmennému konfliktu). Nejpohodlnější řešení je vytvořit aliasy:

1
2
$ alias bat=batcat
$ alias fd=fdfind

nebo symbolické odkazy v ~/.local/bin/.


Související posty