Hoppa yfir í efnið

Leitað og farið yfir

Verkefnasafn

Þessi kafli hefur tilheyrandi verkefnasafn á fylgiþjóninum. Til að sækja það og byrja að leysa verkefnin geturðu keyrt skipunina:

fetch searching-and-exploration

Skráakerfið getur orðið stórt og flókið. Stundum vitum við að skrá er til, en munum ekki hvar hún er. Stundum vitum við að ákveðið orð er inni í einhverri skrá, en ekki hvaða skrá. Linux býður upp á öflug leitartól geta sparað mikinn tíma.

Öll dæmin í þessum kafla gera ráð fyrir að þú sért inni í æfingamöppunni ~/examples og til að tryggja að við séum á réttum stað getum við byrjað á því að færa okkur þangað með skipuninni

cd ~/examples
sem kemur okkur í rétta vinnslumöppu.

Algildistákn

Áður en við skoðum sérstök leitarforrit skulum við skoða svokölluð algildistákn (e. wildcards eða globs). Þetta eru tákn sem skelin túlkar áður en skipunin sjálf keyrir.

Eitt tákn

Spurningamerkið ? er algildistákn sem stendur fyrir nákvæmlega eitt tákn (e. character). Ef þú skrifar í skelina ab? myndi það mátast við (e. match) skrár eða möppur með þriggja stafa nafn sem byrjar á ab, t.d. abc, abö, ab$ og ab😊.

Mörg tákn

Stjarnan * er algildistákn sem stendur fyrir hvaða fjölda tákna sem er, þar með talið ekkert tákn. Ef þú skrifar í skelina ab* myndi það mátast við allar skrár og möppur með nafn sem byrjar á ab, t.d. ab, abc, absurdly_long_name og ab(╯°□°)╯︵ ┻━┻.

Mengi

Hornklofar [] skilgreina svokölluð mengi (e. sets) af táknum sem við viljum máta við. Tvær leiðir eru til að skilgreina hvaða tákn mengið á að máta við. Annars vegar má setja þau beint í mengið, en [ace] stendur fyrir a, c eða e. Hins vegar getum við gefið upp bil, eins og [0-9] sem mátast við alla tölustafina eða [a-z] sem mátast við alla enska bókstafi, en þó ekki hástafi. Einnig er hægt að blanda saman þessum rithatum í einu mengi. Þannig mátast ab[a-z😊] við abc, aba, ab😊 en ekki abö eða ab$.

Til þess að sjá algildistáknin í verki getum við prófað að keyra skipanir á borð við

ls *.md
ls *
ls verkefni-?.txt
[GEMINI: Remind me to add examples that test the behavior of ? and sets]
þar sem skelin finnur sjálfkrafa allar skrár sem passa við viðkomandi munstur og framkvæmir skipanirnar á þeim.

Mikilvægt er að hafa í huga að skipanirnar, þ.e. forritin, sem við keyrum sjá ekki algildistáknin. Skelin sér fyrst um að finna skrár og möppur sem máta við algildistáknin, sem við köllum að þenja út (e. expand) algildistáknin. Sá listi er svo afhentur skipuninni. Þetta getum við sannreynt t.d. með því að keyra

echo *
en þar sjáum við hvaða viðföng skipunin echo fékk, sem ætti einmitt að stemma við öll skráa- og möppunöfn í vinnumöppunni.

Algildistákn passa við skráarnöfn í núverandi samhengi. Ef engin skrá passar er hegðunin aðeins mismunandi milli skelja, en á fylgiþjóninum fáum við villu frá skelinni um að ekkert stemmi við segðina (e. expression), t.d.

$ ls *.ekkitil
zsh: no matches found: *.ekkitil

Prófaðu: algildistákn

Notaðu ls til að finna allar .txt skrár í notes/ og allar skrár í data/ sem byrja á bókstafnum c.

Lausn

Við getum framkvæmt þessa leit með því að keyra skipanirnar

ls notes/*.txt
ls data/c*
sem sía skrárnar út á fljótlegan hátt.


Að finna skrár

find

Skipunin find er notuð til að leita að skrám og möppum eftir nafni eða öðrum eiginleikum eins og stærð og aðgansheimildum. Skipunin er gríðarlega öflug og ýmislegt hægt að stilla þegar kemur að leitinni og því getur stumdum reynst snúið að nota hana.

Í sínu einfaldasta formi, ef engin leitarskilyrði eru gefin, skrifar hún einfaldlega út allar skrár og möppur í þeirri möppu sem leitað er í. Þannig mun

find ~/examples

sýna okkur allar skrár og möppur í ~/examples. Ef engin mappa er gefin upp til að leita í, leitar find í vinnumöppunni, .. Ef við prófum að fara inn í ~/examples og keyra aftur

find

fáum við sömu skrár og með fyrri skipuninni. Athugum samt að slóðirnar birtast ekki eins með fyrri skipuninni birtust algildar slóðir eins og

/home/skoli1/examples
/home/skoli1/examples/permissions
/home/skoli1/examples/permissions/run_me.sh

þar sem viðfangið í find var afstæð slóð (munum að ~ er stytting á /home/skoli1 í þessu tilfelli) en með seinni skipuninni fáum við afstæðar slóðir

./permissions
./permissions/run_me.sh
./permissions/private_note.txt

þar sem sjálfgefna slóðin er afstæð.

Skipunin find er ólík flestum öðrum skipunum þegar kemur að viðföngum og stillingum. Algengast er, þegar kallað er á skipanir, að gefa upp stillingar fyrst, svo viðföng, eins og í hvaða möppu við ætlum að leita. Aftur á móti er upbygging kvaðningar find eftirfarandi

find [mappa sem á  leita í] skilyrði aðgerðir

Til að finna allar skrár eða möppur sem bera ákveðið nafn er hægt að nota -name skilyrðið. Prófum, t.d. að keyra eftirfarandi skipanir í heimamöppunni.

find -name binary     # Ætti að finna ./examples/binary
find -name hello.sh   # Ætti að finna ./examples/scripts/hello.sh

Til að finna skrár og möppur óháð há- og lágstöfum má nota -iname

find -name hello.Sh   # Ætti ekki að finna neitt
find -iname hello.Sh  # Ætti að finna ./examples/scripts/hello.sh

Í -name og -iname skilyrðum má einnig nota algildistákn eins og ? og * til að leita að skrám og möppum sem máta við mynstur. T.a.m. leitar

find -iname "*.sh"
að öllum skrám og möppum sem enda á .sh. Athugum að hér er mikilvægt að nota gæsalappir utan um algildistáknið *, því annars túlkar skelin það sem algildistákn og reynir að finna skrár og möppur sem máta við *.sh í vinnumöppunni og setur nöfn þeirra sem viðföng í kvaðninguna.

Eftirfarandi tafla sýnir dæmi um önnur leitarskilyrði sem hægt er að beita í find. Athugið að þetta er aðeins lítið brot af þeim skilyrðum sem eru í boði.

Skilyrði Hvað Dæmi um viðföng
-type Tegund skrár f er skrá, d er mappa
-maxdepth Hversu djúpt á að leita frá upphafsmöppunni 1 leitar bara í upphafsmöppunni, 2 leitar bara í upphafsmöppunni og þeim möppum sem hún inniheldur, og svo koll af kolli
-size Stærð skráa 500 skrá sem er nákvæmlega 500 bæti, +10M skrá sem er stærri en 10 megabæti, -100K skrá sem er minni en 100 kílóbæti
-mtime Sólarhringar síðan skrá var síðast breytt -1 síðast breytt síðasta sólarhring, +1 síðasta breyting átti sér stað fyrir meira en sólarhring síðan

Engin takmörk eru á fjölda skilyrða sem hægt er að gefa find og því getum við blandað þeim saman að vild.

find ~/verkefni -type f             # Eingöngu skrár í möppunni ~/verkefni
find -type d                        # Eingöngu möppur í vinnuskránni
find -maxdepth 2 -type f            # Eingöngu skrár í upphafsmöppunni og í undirmöppum hennar
find -mtime -1 -size +10M           # Skrám breytt síðasta sólarhring sem eru stærri en 10 MB

Auk þess að finna skrár, getur find einnig framkvæmt aðgerðir beint á þær skrár sem finnast. Aðgerðirnar koma á eftir skilyrðinum í kvaðningunni. Eitt dæmi um aðgerð er -delete sem einfaldlega eyðir skrá, þannig mun skipunin

find -type f -name "*.tmp" -delete
eyða öllum skrám sem hafa endinguna .tmp.

Öflugasta og líklega mest notaða aðgerðin sem notuð er með find er -exec sem keyrir skeljarskipun að okkar vali fyrir hverja skrá sem finnst. Viðfang þessarar aðgerðar er sniðmát skipunarinnar sem á að keyra. Í sniðmátinu táknar {} hverja skrá sem finnst og \; segir find að skipuninni sé lokið. Þannig mun skipunin

find . -type f -name "*.txt" -exec wc -l {} \;

finna allar skrár sem hafa endinguna .txt og keyra skipunina wc -l [slóð á skránna] fyrir hverja og eina, þ.e. hún mun prenta út fjölda lína í öllum skrám með endinguna .txt undir núverandi möppu. Athugið að þegar -exec aðgerðin er notuð eru nöfn skráa og mappa ekki lengur prentuð út, heldur er frálag skipunarinnar sem -exec keyrir skrifað út í stðainn. Það sama á við um aðrar aðgerðir eins og -delete. Í rauninni er það sérstök aðgerð að prenta út nafn þeirra mappa og skráa sem finnast, en það er einmitt -print aðgerðin sem er sjálfgefin.

Prófaðu áður en þú eyðir

Áður en þú notar eyðingarfánann -delete er skynsamlegt að keyra leitina fyrst óbreytta með skipuninni

find . -name "*.tmp"
svo þú sjáir nákvæmlega hvaða skrár munu hverfa áður en þú framkvæmir eyðinguna.

Finndu nálina

Ein skrá í search/ heitir needle.txt. Finndu hana og lestu innihaldið.

Lausn

Við getum fundið skrána og lesið hana með því að keyra skipanirnar

find search -name "needle.txt"
cat search/mystery/deep/path/needle.txt
sem leiðir okkur beint að leyndu innihaldi hennar.

Stærðir og tími

Finndu allar textaskrár undir search/ og láttu wc -l telja línurnar í þeim.

Lausn

Til að finna skrárnar og telja línurnar samtímis getum við beitt skipuninni

find search -name "*.txt" -exec wc -l {} \;
sem skilar okkur heildarfjöldanum á fljótlegan hátt.

fd

Á fylgiþjóninum er búið að setja upp annað leitarforrit, fd. Það er yngra og nútímalegra en find og töluvert einfaldara í notkun. T.a.m. til að finna allar skrár og möppur sem innihalda ar er nægir að keyra

fd ar

Hægt er að framkvæma sömu leitir og aðgerðir með fd og find, en í sumum tilfellum hafa þær aðeins aðra uppbyggingu. Við ætlum ekki að fara í ítarlega kynningu á muninum hér, en alltaf má skoða man fd til að fræðast betur um hann.


Að finna forrit

Þegar þú skrifar ls þarf skelin að finna nákvæmlega hvaða forrit á að keyra. Til að kanna hvar eru staðstett í kerfinu og hvernig þau eru skilgreind getum við keyrt skipanir á borð við which og type. Þessar skipanir þjóna sama tilgangi, en stærsti munurinn á þeim er að which er forrit á meðan type er skeljarskipun, þ.e. hluti af skelinni sjálfri.

Báðar skipanir greina hvort gefið viðfang sé innbyggð skipun í skelinni, samnefni (e. alias) eða forrit. Eftirfarandi eru dæmi um frálag frá báðum skipunum.

$ which cd
cd: shell built-in command
$ which ls
ls: aliased to ls --color=auto --group-directories-first
$ which find
/usr/bin/find
$ type cd
cd is a shell builtin
$ type ls
ls is an alias for ls --color=auto --group-directories-first
$ type find
find is /usr/bin/find

Hér tökum við eftir að þegar við keyrum ls þá erum við í raun að keyra ls --color=auto --group-directories=first. Þetta er gert með svokölluðu samnefni, sem sett er upp í stillingaskrá allra notenda á fylgiþjóninum. Samnefni eru í rauninni bara styttingar á lengri skipunum og stillingum sem við notumst oft við og viljum ekki þurfa að skrifa í hvert skipti. Til að sjá öll samnefni sem eru virk í skelinni má nota skipunina alias. Ef við viljum keyra skipanir sem hafa sama nafn og samnefni, t.d. ef við viljum keyra ls án stillinganna sem setta eru í samnefninu, getum við nota öfugt skástrik á undan skipuninni, þ.e. \ls.


Textaleit

Við höfum nú séð hvernig við leitum að skrám og möppum eftir nafni og eiginleikum, en hvað með innihald skráa? Ýmis forrit eru í boði sem leita eftir innihalda í skrám, en skipunin grep (stytting á global regular expression print) er líklega sú best þekkta og fylgir með flestum, ef ekki öllum, útgáfum Linux. Skipunin leitar að mynstri inni í skrám og prentar út þær línur sem stemma við mynstrið. Til að leita að tilteknum orðum eða strengjum getum við keyrt skipanir á borð við

grep "ERROR" logs/error.log
grep -i "error" logs/error.log       # óháð há/lágstöfum
grep -n "ERROR" logs/error.log       # sýna línunúmer
grep -v "ERROR" logs/error.log       # sýna línur sem passa ekki
grep -r "leit" .                     # leita endurkvæmt í möppum
en gott er að hafa í huga að ef ekkert finnst mun grep ljúka keyrslu án þess að sýna nokkuð á skjánum.

Gagnlegar stillingar:

  • -i: hunsa mun á há- og lágstöfum.
  • -n: sýna línunúmer.
  • -r: leita endurkvæmt í möppum.
  • -v: snúa leitinni við, sýna það sem passar ekki.
  • -l: sýna bara skráarnöfn sem innihalda samsvörun.
  • -E: notar alla eiginleika reglulegra segða.

Nokkur gagnleg mynstur

Við getum einnig látið grep nota reglulegar segðir (e. regular expressions) til að leita að flóknari mynstrum í texta. Með skipunum eins og

grep "^root" /etc/passwd       # línur sem byrja á root
grep "bash$" /etc/passwd       # línur sem enda á bash
grep -E "[0-9]{3}" skrá.txt    # þrír tölustafir í röð
grep -E "cat|dog" skrá.txt     # cat eða dog
getum við síað texta út frá staðsetningu orða í línum eða ákveðnum stafabilum.

Reglulegar segðir mynda mynstur sem er mátað við textann sem er leitað í. Mynstrin hafa mismunandi merkingu, en hér förum við mjög létt yfir algeng mynstur

Textamynstur

Flest mynstur í reglulegum segðum stemma við ákveðinn texta. Öll tákn sem hafa ekki sérstaka merkingu stemma við sjálf sig, þ.e. a, % og 😊 stemma öll við sjálf sig.

Með reglulegum segðum er hægt að skilgreina mengi, með [], sem hafa svipaða merkingu og algildistáknið. Mengi geta innihaldið einstaka stafi eins og [ac$] sem stemmir við a, c eða $. Mengi má einnig skilgreina sem bil eins og [0-9] sem stemmir við einn tölustaf, [a-z] sem stemmir við einn (enskan) lágstaf og [a-zA-Z] sem stemmir við einn lág- eða hástaf.

Þar að auki höfum við mynstrið . sem stemmir við nákvæmlega eitt tákn.

Staðsetningarmynstur

Sum mynstur í reglulegum segðum stemma ekki við neinn ákveðinn texta, heldur við staðsetningar í textanum. Dæmi um slík mynstur eru ^ sem stemmir við upphaf línu og $ sem stemmir við lok línu. Þar að auki er mynstrið \b sem stemmir við orðjaðar (e. word boundary), þ.e. staðsetingu í textanum þar sem stafurinn á undan er bókstafur, tölustafur eða undirstrik (_) og stafurinn á eftir er það ekki; eða öfugt.

Magnarar

Magnarar eru mynstur sem segja til um hversu oft mynstrið sem kemur á undan á að stemma, en stemma ekki sjálf við neinn ákveðinn texta.

Mynstrið * táknar að mynstrið sem kemur á undan eigi að stemma aldrei eða oftar, en + merkir einu sinni eða oftar (virkar aðeins með stillingunni -E). Þannig stemmir mynstrið ab* við alla strengi sem innihalda eitt a með hvaða fjölda sem er af b í kjölfarið, þ.e. a, ab, abb, abbb, o.s.frv. Aftur á móti stemmir ab+ við ab, abb, abbb, o.s.frv.

Hægt er að segja nákvæmlega til um hversu oft við viljum að mynstur stemmi með teljurum sem eru táknaðir með slaufusvigum {}. Til að mynda segir {3} að mynstur eigi að mátast nákvæmlega þrisvar sinnum, {3,5} segir að það eigi að mátast þrisvar til fimm sinnum, {,10} allt að tíu sinnum og {5,} fimm sinnum eða oftar. Þannig stemmir ab{5} eingöngu við abbbbb, en ab{1,3} við ab, abb og abbb.

Pípan a|b leyfir okkur að skilgreina nýtt mynstur, nokkurs konar eðun, með tveimur öðrum mynstrum, a og b. Texti sem stemmir annað hvort við mynstrið a eða b stemmir þá við a|b, og því er þetta oft lesið a eða b líkt og rökfræðileg eðun.

Reglulegar segðir

Eins og fram hefur komið eru reglulegar segðir tungumál út af fyrir sig. Fæst verkefnin sem fylgja þessu kennsluefni krefjast djúprar þekkingar á þeim. Flest verkefnin er þannig hægt að leysa með einföldum og algengum mynstrum.

Prófaðu: grep

Finndu orðið norðurljós í öllum skrám undir search/. Sýndu líka línunúmer.

Lausn

Við getum leitað endurkvæmt og látið fylgja með línunúmer með því að keyra

grep -rn "norðurljós" search
sem prentar allar samsvaranir á skjánum.

Prófaðu: einfalt regex

Í data/scores.csv eru nöfn, hópar og stig. Finndu línur sem enda á tölu á bilinu 90–99.

Lausn

Við getum notað reglulega segð með -E fánanum og keyrt skipunina

grep -E "9[0-9]$" data/scores.csv
til að fá einungis þær línur sem enda á viðeigandi tölubili.

Prófaðu: hvaða skrár nefna Linux?

Finndu skráarnöfn, ekki línur, undir heimamöppunni sem innihalda orðið Linux eða linux.

Lausn

Við getum látið grep birta eingöngu skráarnöfn með því að keyra

grep -ril "linux" .
sem listar upp allar viðeigandi skrár.


Að fá hjálp

Það er ómögulegt að muna allar stillingar skipana utanað og þess vegna er mikilvægt að kunna að leita sér upplýsinga þegar þörf er á. Skipunin man (stytting á manual) sýnir ítarlegar notkunarupplýsingar fyrir forrit, þ.e. stillingar, dæmi um notkun og ýmsar aðrar nytsamlegar upplýsingar. Til dæmis má sjá notkunarleiðbeiningar grep með

man grep
Leiðbeiningarnar eru opnaðar í sjálfgefnum síðufletti (less á fylgiþjóninum).

Flestar skipanir og forrit bjóða upp á þann möguleika að skrifa út fyrir okkur stuttar leiðbeiningar um notkun. Þær eru yfirleitt ekki jafn ítarlegar og þær sem við fáum með man, en duga oft til að sjá algengar stillingar og viðföng. Hefðin er sú að stillingin sem kalli fram leiðbeiningarnar sé --help. Sumar skipanir bjóða einnig upp á styttinguna -h, en það er líka hefð fyrir því að sú stilling sýni styttri hjálp en --help.

grep -h              # stutt hjálparsíða
grep --help          # ítarlegri hjálparsíða
cat -h               # ekki í boði
cat --help           # hjálparsíða

Á fylgiþjóninum er búið að setja upp tólið tldr (stytting á too long; didn't read). Markmið tólsins er að halda utan um safn hnitmiðaðra og stuttra leiðbeininga á algengustu notkun skipana. Upplýsingarnar eru sóttar í stórt safn sem er viðhaldið af áhugasömum einstaklingum um allan heim. Með skipunum eins og

tldr tar
tldr grep
fáum við þannig einföld og hagnýt dæmi um notkun skipananna án þess að þurfa að lesa heilu handbækurnar.

Vissir þú?

Nafnið grep kemur úr gamla textaritlinum ed. Þar var skipunin g/re/p notuð fyrir „global regular expression print“. Það hljómar dularfullt, en hugmyndin er einföld: finna línur sem passa við mynstur og prenta þær.

Verkefni

Hér má finna öll verkefnin úr efni þessa kafla.

Opna verkefni