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

8. Hledání souborů

Řada 1.x vanilkové příchuti Linuxu: Knihy kouzel je od 1. října 2020 do 1. března 2023 ve stavu dlouhodobé pasivní údržby; nahlášené chyby budou opravovány, ale aktivní vývoj se již věnuje novější vývojové řadě určené pro novější verze operačního systému a programů. Pokud nejste vázáni na starší verze programů, doporučuji vyhledat novou verzi z aktivně vyvíjené vývojové řady.
adresáře hledání tematický okruh

1. Úvod

Tato kapitola se zabývá vyhledáváním adresářových položek (souborů a adresářů). Převážně se zabývá příkazem „find“, který strukturu adresářů skutečně prochází a prohledává, ale zahrnuje také vyhledávání programů a na databázi založený příkaz „locate“.

Tato verze kapitoly nepokrývá vyhledávání podle obsahu souboru.

2. Definice

3. Zaklínadla (find: testy)

3/1 Typ adresářové položky (soubor, adresář, odkaz...)

ˑobyčejný soubor#1
-type f
adresář#2
-type d
˦symbolický odkaz (jakýkoliv/na soubor/na adresář/absolutní/relativní)#3
-type l
-type l -xtype f
-type l -xtype d
-lname "/*"
-type l \! -lname "/*"
ˑspeciální zařízení (blokové/znakové/jakékoliv)#4
-type b
-type c
-type b,c
pojmenovaná roura#5
-type p
soket#6
-type s

3/2 Název položky a cesta

Písmeno „i“ vypne rozlišování mezi velkými a malými písmeny.

název položky#1
-[i]name "vzorek"
cesta položky#2
-[i]path "vzorek"
cesta položky se shoduje s regulárním výrazem#3
[-regextype posix-extended] -[i]regex 'regulární výraz'
hodnota symbolického odkazu#4
-[i]lname "vzorek"

3/3 Velikost souboru

M až N gibibajtů/mebibajtů/kibibajtů/bajtů#1
-size +$((M*2**30-1))c -size -$((N*2**30+1))c
-size +$((M*2**20-1))c -size -$((N*2**20+1))c
-size +$((M*2**10-1))c -size -$((N*2**10+1))c
-size +$((M-1))c -size -$((N+1))c
M až N gigabajtů/megabajtů/kilobajtů/bajtů#2
-size +$((M*10**9-1))c -size -$((N*10**9+1))c
-size +$((M*10**6-1))c -size -$((N*10**6+1))c
-size +$((M*10**3-1))c -size -$((N*10**3+1))c
-size +$((M-1))c -size -$((N+1))c
minimálně N gibibajtů/mebibajtů/kibibajtů/bajtů#3
-size +$((N*2**30-1))c
-size +$((N*2**20-1))c
-size +$((N*2**10-1))c
-size +$((N-1))c
maximálně N gibibajtů/mebibajtů/kibibajtů/bajtů#4
-size -$((N*2**30+1))c
-size -$((N*2**20+1))c
-size -$((N*2**10+1))c
-size -$((N+1))c
minimálně N gigabajtů/megabajtů/kilobajtů#5
-size +$((N*10**9-1))c
-size +$((N*10**6-1))c
-size +$((N*10**3-1))c
-size +$((N-1))c
maximálně N gigabajtů/megabajtů/kilobajtů#6
-size -$((N*10**9+1))c
-size -$((N*10**6+1))c
-size -$((N*10**3+1))c
-size -$((N+1))c
přesně N gibibajtů/mebibajtů/kibibajtů/bajtů#7
-size $((N*2**30))c
-size $((N*2**20))c
-size $((N*2**10))c
-size Nc
přesně N gigabajtů/megabajtů/kilobajtů/bajtů#8
-size $((N*10**9))c
-size $((N*10**6))c
-size $((N*10**3))c
-size Nc
prázdný soubor#9
-size 0

3/4 Čas („změněno“, „čteno“)

změněno/čteno v rozsahu dnů#1 (1)
-newermt "první-den-intervalu 00:00:00" \! -newermt "poslední-den-intervalu 23:59:59"
-newerat "první-den-intervalu 00:00:00" \! -newerat "poslední-den-intervalu 23:59:59"
čteno od poslední změny#2

3/5 Operátory testů

oba testy musejí být splněny (a také)#1
test1 test2
test nesmí být splněn (ne-)#2
\! test
závorky (seskupení testů a akcí)#3
\( testy a akce \)
některý z testů musí být splněn (nebo)#4
test1 -o test2

3/6 Vlastnictví a skupina položky

vlastník souboru (názvem/UID)#1
-user uživatel
-uid UID
skupina (názvem/GID)#2
-group skupina
-gid GID

3/7 Přístupová práva (ACL)

soubor je přístupný pro čtení#1
-readable
soubor je přístupný pro zápis#2
-writable
soubor je fakticky spustitelný#3
-executable
vlastník (u), skupina (g) či ostatní (o) mají právo (jedno z r, w, x)#4
-perm /kdo=právo
\! -perm /kdo=právo
všichni mají určité právo#5
-perm -ugo=právo
vlastník (u), skupina (g) či ostatní (o) mají všechna práva#6
-perm -kdo=rwx

3/8 Obsah souboru

některý řádek obsahuje/žádný řádek neobsahuje shodu s regulárním výrazem#1
\! ( -type d -o ( -type l -xtype d ) ) -readable -exec egrep -q [--] 'regulární výraz' \;
\! ( -type d -o ( -type l -xtype d ) ) -readable \! -exec egrep -q [--] 'regulární výraz' \;
některá řádka obsahuje/žádná řádka neobsahuje podřetězec#2
\! ( -type d -o ( -type l -xtype d ) ) -readable -exec fgrep -q [--] 'podřetězec' \;
\! ( -type d -o ( -type l -xtype d ) ) -readable \! -exec fgrep -q [--] 'podřetězec' \;

3/9 Velikost adresáře

prázdný adresář#1
-type d -empty
adresář s alespoň N položkami/právě N položkami/nejvýše N položkami#2
-type d -exec sh -c 'test $(ls -1AbU -- "$1" | wc -l) -ge N' -- '{}' \; [--print]
-type d -exec sh -c 'test $(ls -1AbU -- "$1" | wc -l) -eq N' -- '{}' \; [--print]
-type d -exec sh -c 'test $(ls -1AbU -- "$1" | wc -l) -le N' -- '{}' \; [--print]

3/10 Ostatní

pevné odkazy konkrétního souboru#1
-samefile soubor
neplatné symbolické odkazy#2
-type l -xtype l
počet pevných odkazů (přesně/minimálně/maximálně N)#3
-links N
-links +$((N-1))
-links -$((N+1))
obsah symbolického odkazu odpovídá vzorku#4
-lname 'vzorek'
test, který vždy uspěje/selže#5
-true
-false
vlastník nebo skupina souboru neexistuje#6
\( -nogroup -o -nouser \)
typ souborového systému#7 (2)
-fstype typ
čislo inode#8
-inum inode
hloubka prohledávání#9

4. Zaklínadla (find: akce)

4/1 Vypsat údaje

cestu položky na standardní výstup (txt/txtz)#1
-print
-print0
vypsat údaje podle formátu na standardní výstup/do souboru#2
-printf 'formát'
-fprintf soubor 'formát'
zapsat cestu položky jako záznam do souboru (txt/txtz)#3 (3)
-fprint soubor
-fprint0 soubor

4/2 Ostatní akce

smazat soubor či prázdný adresář (lze použít jen při průchodu do hloubky)#1 (4)
-delete
spustit příkaz po dávkách#2 (5)
-exec příkaz [parametry příkazu] '{}' +
spustit příkaz po dávkách po adresářích#3 (6)
-execdir příkaz [parametry příkazu] '{}' +
spustit příkaz pro každou položku (s cestou/bez cesty)#4 (7)
-exec příkaz [parametry příkazu] \;
-execdir příkaz [parametry příkazu] \;
je-li položka adresář, nevstupovat do něj a ignorovat jeho obsah (funguje jen při průchodu do šířky)#5
-prune
ukončit načítání dalších položek#6
-quit

5. Zaklínadla (akce -printf a -fprintf)

ˑnázev položky/cesta položky/cesta položky bez výchozího bodu#1
%f⊨ test.txt
%p⊨ ./testdir/test.txt
%P⊨ testdir/test.txt
typ adresářové položky (písmeno)#2
%y⊨ f
cesta položky bez názvu#3
%h⊨ ./testdir
výchozí bod#4
%H⊨ .
čas „změněno“(normálně/časová známka Unixu)#5 (8)
%TY-%Tm-%Td %TT⊨ 2020-03-13 22:03:00.9467889490
%T@⊨ 1584133380.9467889490
čas posledního přístupu (normálně/časová známka Unixu)#6 (9)
%AY-%Am-%Ad %AT⊨ 2020-03-13 22:03:00.9467889490
%A@⊨ 1584133380.9467889490
hloubka prohledávání#7
%d⊨ 1
typ souborového systému#8
%F⊨ ext4
cíl (obsah) symbolického odkazu#9 (10)
%l
počet pevných odkazů#10
%n⊨ 1
velikost souboru v bajtech#11
%s⊨ 3
vlastník (jméno/UID)#12
%u⊨ milada
%U⊨ 1000
skupina (jméno/GID)#13
%g⊨ milada
%G⊨ 1000
číslo „inode“#14
%i⊨ 2758499
přístupová práva symbolicky#15
%M⊨ -rw-r--r--

6. Zaklínadla (celé příkazy)

6/1 Hledání textových souborů podle obsahu

najít soubory, jejichž některá řádka obsahuje/žádný řádek neobsahuje shodu s regulárním výrazem#1
find kde -type f -readable [další podmínky] -exec egrep -l 'regulární výraz' '{}' +
find kde -type f -readable [další podmínky] -exec egrep -L 'regulární výraz' '{}' +
najít soubory, jejichž některá řádka obsahuje/žádný řádek neobsahuje podřetězec#2
find kde -type f -readable [další podmínky] -exec fgrep -l 'regulární výraz' '{}' +
find kde -type f -readable [další podmínky] -exec fgrep -L 'regulární výraz' '{}' +
najít symbolické smyčky, tzn. symbolické odkazy, které přímo či nepřímo odkazují samy na sebe#3
find kde -type l -printf '%Y%p\0' | sed -zE 's/^L//;t;d' [| tr \\0 \\n]

6/2 Hledání programů

najít úplnou cestu podle názvu příkazu#1 (11)
which název-příkazu
najít manuálové stránky (jako soubory/název a sekce)#2
find -L /usr/share/man -type f -name 'název.*.gz' [| sort]
find -L /usr/share/man -type f -name 'název.*.gz' | sed -E 's/.*\/(.*)\.([^.]+)\.gz$/\1(\2)/' | sort -u

6/3 Obecné hledání

najít a odstranit prázdné adresáře/soubory/soubory i adresáře#1
find kde -type d -empty -delete
find kde -type f -empty -delete
find kde -empty -delete
najít neplatné symbolické odkazy (pro člověka/pro skript)#2 (12)
[sudo] find kde -type d -exec symlinks '{}' + | egrep '^dangling: '
[sudo] find kde -type l -xtype l [-print0]
najít adresářové položky, jejichž názvy/celá cesta obsahují shodu s regulárním výrazem (pomoc databáze „mlocate“)#3
[sudo] locate --regex -b [-e] [-i] -r 'regulární výraz pro název položky'
[sudo] locate --regex [-e] [-i] -r 'regulární výraz pro celou cestu'

7. Parametry příkazů

7/1 find

[sudo] find [-P] cesta globální parametry testy-a-akce
[sudo] find -L cesta globální parametry testy-a-akce
[sudo] find -H cesta globální parametry testy-a-akce

Chování k symbolickým odkazům: -P: nikdy nenásledovat (interpretovat každý odkaz jen jako adresářovou položku); -L: vždy následovat (chovat se, jako by na místě symbolického odkazu byl odkazovaný soubor, adresář apod.; vstupovat do takových adresářů); -H: následovat jen symbolické odkazy, které jsou přímo uvedeny jako „cesta“ na příkazové řádce.

Globální parametry:

☐ -xdevPo každou „cestu“ na příkazové řádce omezí prohledávání jen na jeden souborový systém.
☐ -depthAdresář zpracuje až „na odchodu“, tzn. teprve po zpracování veškerého jeho obsahu. Normálně se adresář zpracuje jako první a pak se teprve testuje jeho obsah.
☐ -maxdepth čísloSestoupí maximálně do uvedené hloubky. 0 znamená testovat jen cesty uvedené na příkazové řádce; 1 znamená testovat i položky v adresářích uvedených na příkazovém řádku; 2 znamená testovat i položky v podadresářích těchto adresářů atd.
☐ -mindepth čísloNa položky v hloubce nižší než „číslo“ se nebudou aplikovat žádné testy ani akce a nebudou vypsány. Pozor, to znamená, že na ně nebude účinkovat akce -prune! Příkaz find se pokusí vstoupit do každého adresáře s hloubkou menší než „mindepth“.

Testy a akce jsou uvedeny jako zaklínadla v předchozí části kapitoly.

8. Instalace na Ubuntu

Většina uvedených příkazů je základními součástmi Ubuntu. Pouze příkaz „symlinks“ musíte v případě potřeby doinstalovat:

sudo apt-get install symlinks

9. Tipy a zkušenosti

10. Další zdroje informací

ve výstavbě
1 Dny zadejte ve formátu %F (YYYY-MM-DD).
2 Např. „ext4“, „tmpfs“, „ntfs“, „vfat“.
3 Poznámka: Varianta „txt“ není bezpečná v případě, že cesta položky obsahuje znak konce řádku.
4 Akce uspěje, pokud se soubor či adresář podaří smazat.
5 Tato varianta je prakticky ekvivalentem volání příkazu xargs. Použije co největší dávky. Vždy uspěje.
6 Tato varianta vždy uspěje. Shromáždí položky z jednotlivého adresáře a po velkých dávkách (obvykle najednou) je předá ke zpracování uvedenému příkazu. Příkaz se spouští v adresáři, kde jsou vyhledané položky, a dostává pouze název souboru s cestou „./“.
7 Každý výskyt řetězce „{}“ v parametrech příkazu bude při volání nahrazen: v případě první varianty cestou testované položky od výchozího bodu, v případě varianty bez cesty jen názvem souboru s cestou „./“ (příkaz bude spuštěn ve stejném adresáři, kde se položka nachází). Akce uspěje, pokud uspěje příkaz.
8 V obou případech se bohužel vypíše s desetinnou částí.
9 V obou případech se bohužel vypíše s desetinnou částí.
10 Pokud položka není symbolický odkaz, %l vypisuje prázdný řetězec.
11 Poznámka: tento příkaz (pochopitelně) ignoruje vestavěné příkazy bashe, aliasy, funkce apod. Řídí se pouze proměnnou prostředí PATH.
12 Pozor! Příkaz nemůže správně určit, zda je symbolický odkaz neplatný, pokud nemá přístupová práva k adresáři, na který symbolický odkaz odkazuje! Příkaz „symlinks“ v takovém případě hlásí odkaz jako neplatný, uvedená podoba příkazu „find“ vypíše chybové hlášení „Permission denied“, ale odkaz do seznamu neplatných nezahrne.
SystémSpráva uživatelských účtůMarkdown