Gábor Karai
Operációs rendszerek gyakorlat
Olvass el!
Kurzusleírás
Nappali és levelező tagozatos kurzusleírás részletes számonkérési rendszerrel együtt
Eligazító dokumentum a Courserás teljesítést választó hallgatók számára
Hagyományos és Courserás teljesítés összehasonlítása nappali tagozaton és levelező tagozaton
Tematika
A gyakorlaton GNU/Linux (valószínűleg Debian) operációs rendszert használunk, s az alábbi három témára van szétválasztva a féléves anyag:
- Linux: A félév első harmadában Linux terminált fogunk használni. Átveszünk néhány Linux (BASH) parancsot, s elsajátítjuk a hatékony használatukat is (pl. csővezeték).
- BASH (Bourne Again SHell): a második harmadban már programokat fogunk írni Linux parancsokból vezérlési szerkezetek és változók segítségével. A shell az operációs rendszer külső része, mely a felhasználókkal és felhasználói programokkal való kommunikációra szolgál. A shell-nek több típusa is van. Mi a BASH-t fogjuk használni, mely a mai napig az egyik legelterjedtebb.
- AWK: az utolsó részben reguláris kifejezésekkel foglalkozunk, valamint áttérünk az AWK nyelvre, amely egy egyszerű, de hatékony szövegfeldolgozó programozási nyelv. Az AWK nyelv implementációi közül az egyik legelterjedtebbet, a GNU AWK (GAWK) változatot fogjuk használni.
Anyagrészek
L1: parancsok felépítése és súgója, csatornák, UNIX fájlrendszerek, jogosultságok, felhasználók kezelése, cat parancs, átirányítások, műveletek könyvtárbejegyzésekkel, pontosvessző (;) és backslash (\) operátor
L2: linkelés, kiíratás, szöveges fájlok kezelése, csővezeték, sed parancs, mintaillesztés, grep parancs
B1: BASH szkriptek felépítése, változók, parancssori paraméterek, feltételes kifejezések, test parancs
B2: zárójel típusok, vezérlési szerkezetek I. (if, for)
B3: vezérlési szerkezetek II. (while, until, case), ugró utasítások, exit parancs
A1: reguláris kifejezések, AWK szkriptek felépítése, minták, kiíratás
A2: konstansok/változók, operátorok, sztring összefűzés, vezérlési szerkezetek, beépített változók, ugró utasítások
A3: dinamikus reguláris kifejezések, tömbök, beépített szöveges és numerikus függvények
Az aláhúzott elemek kiegészítő anyagrészek, a ZH-k nélkülük is teljesíthetők.
Referencia
A Linux anyagrészek…
- magyar nyelvű fő forrásai a SzabiLinux és a Letix,
- angol nyelvű fő forrása pedig a GNU Coreutils csomag dokumentációja.
A BASH és a GNU AWK anyagrészek fő forrásai a GNU hivatalos online dokumentációi.
A reguláris kifejezéseket tárgyaló anyagrész fő forrása pedig a GAWK dokumentációjának egyik fejezete, ugyanakkor az alap és kiterjesztett reguláris kifejezések általános felépítési/működési elvárásait a POSIX szabvány fejti ki részletesen. A BASH és az AWK nyelv is ezt a szabványt követi.
Továbbra is elérhető a 2020-ban készült oktatóvideó sorozat. Ez már elavultnak számít, ennek tudatában álljon mindenki hozzá!
Gyakorlásra ajánlott a változatos, adott esetben további utánajárást igénylő feladatokat tartalmazó példatár.
További hasznos oktatóanyagok és leírások elérhetők YouTube-on, illetve Google barátunk segítségével még több érdekes dolgot túrhatunk elő tanulmányaink előbbre segítésére az internet sötét bugyraiból.
Motiváció
- Az informatikai cégek jelentős részénél a fejlesztések valamilyen GNU/Linux operációs rendszer alatt zajlanak, így mindeki jól jár azzal, ha ismeri ezeknek a rendszereknek a felépítését és használatát.
- A szkriptnyelvek népszerűnek számítanak az IT világában, ennek megfelelően a BASH ismerete egy jó alap lehet a későbbiekben, ha valaki mondjuk Matlab, Python, Javascript, PHP, Perl, … nyelven szeretne programozni.
- Könnyed keresés és listázás fájlok között, illetve fájlokban keresés és testreszabott adatkiválogatás.
- Linux alatt a programok telepítése egy parancs kiadását jelenti a csomagkezelőnek (Ubuntu és Debian disztribúciókon APT) köszönhetően. Így nem kell egy program telepítésekor a függőségeket kézzel megkeresni és telepíteni.
- A feltelepített csomagok listájának elmentésével egyszerűen reprodukálható egy működő rendszer.
- …
- EXTRA: Amire még jó lehet a BASH. (YouTube)
Linux otthonra
1. Debian, Ubuntu és VirtualBox letöltési lehetőség.
Debian telepítés általános leírása
Debian telepítés VirtualBox-ra (64 bit!) itt (YouTube)
2. Windows alatt:
Cygwin - Linux terminál helyett.
Útmutató Windows 10-en a felhasználónév átnevezéséhez ékezetes és/vagy whitespace karakterek előfordulása esetén: Win10_felhasznalonev_atnevezese.pdf.
Windows Subsystem for Linux (WSL) - virtuális gépen futó Linux terminál.
Telepítése Windows 10-re (YouTube) és Windows 11-re (YouTube).
Notepad++ - gedit forráskódszerkesztő helyett.
CR karakter eltüntetése a sorok végéről Notepad++-ban: NotepadPlusPlus_CRLF.pdf
Útmutató AWK szintaxis kiemelés beállításához Notepad++-ban, valamint a hozzáadandó xml fájlok: NotepadPlusPlus_AWK.pdf, AWK.xml, GAWK.xml
Notepad++ könyvtárának hozzáadása a Path környezeti változóhoz: NotepadPlusPlus_PATH.pdf
VAGY
3. Kabinet elérése:
WinSCP - Csak Windows környezetben használható.
PUTTY - Windows a preferált platform, de Linux rendszerre is telepíthető.
FileZilla - Windows és Linux operációs rendszeren is használható. Online útmutatója is van angol nyelven.
Részletes leírás a kabinet eléréséhez.
Egyéb hasznos információk
A hivatalos kommunikációs platform a CooSpace. Minden fontos információ a gyakorlati kurzusok egyesített színterébe fog felkerülni - többnyire hirdetmény formájában. Ha valakinek kérdése van, bátran keresse a gyakorlatvezetőit CooSpace chat-en. Emellett e-mail-ben is állunk rendelkezésre, az összes gyakorlatvezető elérhetősége megtalálható a CooSpace profiljukon. A gyakorlatvezetők Discordon is jelen vannak. Érdemes csatlakozni a Kalkulusták és a hozzá tartozó MarkMyProf Discord szerverhez. A MarkMyProfessor oldal újra üzemel, ahol a fő gyakorlatvezető - Karai Gábor - is névtelenül értékelhető.
GYakran Ismételt Kérdések
Szerezhető-e megajánlott jegy gyakorlati teljesítés alapján az előadás kurzusra?
Komoly előismerettel rendelkezem BASH programozás terén, például gimnáziumból vagy rendszergazda tanfolyam elvégeztével. Kiváltható-e a tárgy?
Bejárhatok-e másik órára, például ütközés vagy munka miatt?
Igazoltan tanulási nehézsége(i)m van(nak). Jogosult vagyok-e valamilyen könnyítésre/kompenzációra?
Visszanézhetők lesznek-e a levelezős online órák?
Nem. Ez a lehetőség jelen tárgy esetében indokolatlan, mert az előadás és a gyakorlat tematikája között nappali és levelező tagozaton is nagyon kevés átfedés van.
Megjegyzés: Az operációs rendszerek gyakorlat elnevezés rendszeresen kap negatív hallgatói kritikát. Itt azt kell megérteni, hogy az előadáson az operációs rendszerek általános működési elvét, fő feladatait ismerteti az oktató, a gyakorlaton az operációs rendszerek külső részére - a SHELL-re - helyezzük a hangsúlyt. A mai napig az egyik legnépszerűbb SHELL típus a BASH, amely minden ismert operációs rendszerre telepíthető (Windows, macOS, GNU/Linux disztribúciók). Hogy ne legyen túlságosan szerteágazó a tematika, ez a programozási nyelv képezi a kurzus nagyobbik felét.
Ha a hallgató korábbi felsőoktatási tanulmányai alatt teljesített ehhez nagyon hasonló kurzust (akár ugyanezt, csak újra kellett felvételiznie), akkor kreditátvitellel lehet elfogadtatni a tárgyat. Ez a tanulmányi osztály hatásköre. Nincs félév eleji kiugró teszt, emiatt nem váltható ki más módon ez a tárgy.
Nem. A géptermi gyakorlatok kapacitása a tantermi gépek rögzített darabszáma miatt szigorúan korlátozott. Külső munkaviszony fenntartása informatikus hallgatóként (is) nagyon hasznos és támogatandó, viszont a hallgató felelőssége - a munkáltató együttműködésével - a munkaidő összeegyeztetése az egyetemi tanulmányaival. Teljes munkaidős állás esetén mindenképpen a levelező tagozat ajánlott, hacsak nem 1-2 tárgya van már csupán hátra a hallgatónak.
Aki bármely okból kifolyólag az online tanfolyamok elvégzését preferálja a jelenléti gyakorlattal és ZH írással szemben, annak a Courserás teljesítési mód való. Elsősorban azoknak ajánlott - amennyiben rendelkeznek kellő szakmai angol nyelvtudással -, akik nehezen tudják megoldani a bejárást, vagy magas szintű előismerettel rendelkeznek.
2023 szeptembere óta a SANSZ iroda nyújt segítséget/eligazítást a speciális képzési igényű (SKI) hallgatók számára. Állapotfelmérés után az általuk kiadott igazolás alapján kizárólag diszlexiában (is) érintett hallgatók számára áll módunkban könnyített körülményt biztosítani, amely nappali és levelező tagozaton is 30% extra kitöltési időt jelent a jelenléti/online számonkéréseken. A Coursera tanfolyamok teljesítésére senkinek sem jár könnyített körülmény. Az igazoló dokumentumot legkésőbb az ötödik szorgalmi hét végéig kell benyújtani az erre a célra létrehozott CooSpace eszközön keresztül!
Oktatói álláspontom szerint a nem kötelező órákon való részvételt - mint az OS is - jutalmazni célszerű. Jelen kurzuson ez abban nyilvánul meg, hogy az oktató olyan kiegészítő információkat, extra gyakorlófeladatok megoldását ismerteti, amelyek írásban nem találhatók meg. Ha felvétel készülne, akkor szinte semmi értelme nem lenne az időponthoz kötött óráknak. Ennek ellenére nem tilthatom meg, hogy valamelyik résztvevő felvételt készítsen - mivel technikailag nem lehet megakadályozni.
Menetrend
Nappali tagozat
Courserás teljesítés
Jelenléti teljesítés
Akik a kurzusfelvétel során az időpont és helyszín nélküli, coursera szövegre végződő kurzusra jelentkeznek fel, számukra a két kitüntetett Coursera tanfolyam elvégzését igazoló tanúsítvány feltöltési határideje május 24., amely a szorgalmi időszak utolsó napja. Mindkét dokumentum szükséges a gyakorlat teljesítéséhez!
Akik valamely jelenléti órás kurzust választják, hagyományos módon teljesíthetik a kurzust az alábbi ütemezéssel.
Fontos! Ekkor a Coursera tanfolyamok elvégzése nem számítható be a kurzus teljesítésébe!
Szorgalmi hét | Dátum | Esemény | |
---|---|---|---|
Szerda | Csütörtök | ||
1. | 02.12. – 02.13. | Kurzusfelvétel, eligazítás | |
2. | 02.19. – 02.20. | L1 | |
3. | 02.26. – 02.27. | L2 | |
4. | 03.05. – 03.06. | B1 | |
5. | 03.12. – 03.13. | B2 | |
6. | 03.19. – 03.20. | B3 | |
7. | 03.26. – 03.27. | 1. ZH | |
8. | 04.02. – 04.03. | A1 | |
9. | 04.09. – 04.10. | A2 | |
10. | 04.16. – 04.17. | Tavaszi szünet | |
11. | 04.23. – 04.24. | A3 | |
12. | 04.30. – 05.01. | Sport Nap | Május 1. |
13. | 05.07. – 05.08. | Gyakorlás | |
14. | 05.14. – 05.15. | 2. ZH | |
15. | 05.21. – 05.22. | Pótló/Módosító ZH |
Levelező tagozat
Az online órákon minden levelezős hallgató részt vehet, nincs két külön kurzus nyilvántartva a két teljesítési mód számára. Itt is május 24. a tanúsítványok feltöltési határideje. Ezen dátumot követően kizárólag sikeres ZH-val teljesíthető a gyakorlat (szükség esetén védéssel együtt).
Dátum | Esemény |
---|---|
03.28. | L1 – L2 |
05.09. | B1 – B3 |
05.23. | A1 – A3 |
05.30. | ZH ‒ 1. lehetőség |
06.06. | ZH ‒ 2. lehetőség |
06.13. | ZH ‒ 3. lehetőség |
L1
Parancsok felépítése és súgója
Általános alak: <parancsnév> [kapcsolók] [parancssori paraméterek]
A parancs neve általában egy értelmes angol szó vagy annak rövidítése. Megadása kötelező.
A kapcsolók opcionális kulcsszavak, melyekkel a parancs valamilyen támogatott funkcióját használhatjuk ki. Mindig '-' (nagy ritkán +) karakterrel kezdődnek, és általában egyszerre többet is alkalmazhatunk. Mivel megkülönbözteti a kis- és nagybetűket, az egybetűs kapcsolók között lehet kis- és nagybetűs változat is (pl. -r és -R), s ezek gyakran teljesen más műveletet végeznek. Néhány kapcsolónak saját argumentuma van, amit közvetlenül utána kell megadni. Ha mindegyiket mellőzzük, a parancs alapértelmezett - a súgója elején olvasható - módon fog viselkedni.
Parancssori paraméterek segítségével általában a feldolgozandó adatot adjuk át a programnak. Ez lehet például tetszőleges szöveg, vagy a fájlrendszerben létező (vagy nem létező) könyvtárbejegyzés útvonala. Nem minden parancs vár paramétert, és gyakran a feldolgozandó adatot standard inputon (billentyűzet, csővezeték) keresztül is tudja fogadni. A paramétereket (is) szóközzel elválasztva kell felsorolni. Emiatt a több szóból álló paramétereket idézőjelek (aposztrófok vagy macskakörmök) közé kell tenni.
<parancs> --help
man [kapcsoló] <parancs>
help [parancs]
<parancs> --version
A kis- és nagybetűk különbözőnek számítanak. A fenti szintaxisból látható, hogy a parancsok három részből állnak:
Bármelyik parancs után írva kiad nekünk a terminál egy kis segítséget az adott parancs használatáról, például kiírja az általános alakját, és röviden ismerteti a kapcsolóit.
A megadott parancs hivatalos dokumentációját hozza be. Általában részletesebb a --help kapcsolónál, viszont nem mindig naprakész.
Paraméter nélkül kilistázza a - help utasítás részéről - súgóval rendelkező beépített utasítások általános alakját. Egyébként a megadott parancs használatáról ad egy kis eligazítást.
Messze nem teljes a támogatott parancsok listája, ráadásul általában nem szolgáltat elegendő információt.
Bármelyik parancs után írva (kevés kivétellel) az adott parancs telepített verziószámát, megjelenése évét és szerzőjét írja ki.
Ezzel a módszerrel arról is meggyőződhetünk, hogy telepítve van-e a kérdéses parancs. Ha nincs, akkor "command not found", azaz "parancs nem található" hibaüzenetet kapunk.
Csatornák
Az informatikai rendszerek általános működési elve szerint a processzusok valamilyen kitüntetett csatornán (channel, stream) keresztül továbbítják egymás között az adatokat, lásd az illusztrációt.
Linux shell környezetben három csatorna van előre definiálva, amiket a beépített shell programok használnak:
stdin (0): Standard bemeneti csatorna. A feldolgozandó adatok átadására használatos, mely leginkább a billentyűzeten begépelés vagy csővezetéken keresztül történő továbbítás formájában valósul meg. Nem mindegyik parancs használja.
stdout (1): Standard kimeneti csatorna. A futás közben keletkezett (rész)eredmények továbbítására használatos. Alapértelmezetten a terminálra van irányítva.
stderr (2): Standard hibacsatorna. A futás közben keletkezett hibaüzenetek továbbítására használatos. Alapértelmezetten ez is a terminálra van irányítva.
Mindegyik csatornának van egy numerikus azonosítója - nemnegatív egész szám, a fentieké zárójelben -, amely megkönnyíti a rájuk való hivatkozást. Erre jellemzően átirányításkor van szükség.
UNIX fájlrendszerek
A fájlrendszer fő feladata a háttértárakon tárolt adatokhoz való hozzáférés biztosítása valamilyen struktúra alapján. A UNIX fájlrendszerek fastruktúrára emlékeztető felépítést követnek, lásd az ábrát.
Minden bejegyzés (pl. alkönyvtárak, közönséges fájlok) pozícióját egy kitüntetett könyvtárhoz, a gyökérkönyvtárhoz viszonyítva adja meg, melynek jele /. Van néhány kötelező könyvtár, ezek közvetlenül a gyökérkönyvtárban helyezkednek el. Ilyen például a /home, melyben a felhasználók saját könyvtára található, ebben tárolhatják a csak általuk elérhető adatokat. A /dev könyvtárban találhatók a fizikai eszközök (pl. adathordozó) és a virtuális eszközök is (pl. kommunikációs csatornák). Jelen kurzuson még a /bin könyvtár kiemelt fontosságú számunkra, ebben található a rendszer legtöbb futtatható állománya, beleértve a terminálban kiadott parancsok futtatható változatát is.
pwd
(print working directory)
Kiírja a munkakönyvtár, vagyis az aktuális könyvtár elérési útvonalát. Vegyük észre, hogy az aktuális könyvtár mindig látható a terminálban.
karaigabor@karaigabor:~/downloads/matlab$ pwd /home/karaigabor/downloads/matlab
cd [könyvtár]
(change directory)
A fájlrendszerben való mozgást teszi lehetővé. Paraméterként a célkönyvtár abszolút vagy relatív elérési útvonalát kell megadni.
Abszolút útvonal
A teljes elérési útvonalat kell megadni, mindig a gyökérkönyvtártól kezdve. Pl.: /home/hxxxxxx/mappa/file1
karaigabor@karaigabor:~$ cd /home/karaigabor/downloads/matlab karaigabor@karaigabor:~/downloads/matlab$
Relatív útvonal
Ebben az esetben azt mondjuk meg, hogy az aktuális, vagyis a munkakönyvtárhoz képest hol helyezkedik el a megcélzott bejegyzés. Például, ha éppen a /home/hxxxxxx-ben vagyunk: ./mappa/file1.
Aktuális könyvtár: .
Szülőkönyvtár: ..
karaigabor@karaigabor:~$ cd downloads/matlab karaigabor@karaigabor:~/downloads/matlab$
Visszalépés a szülő könyvtárba.
karaigabor@karaigabor:~/downloads/matlab$ cd .. karaigabor@karaigabor:~/downloads$ cd .. karaigabor@karaigabor:~$
Két szinttel feljebb lépés, vagyis a szülőkönyvtár szülőkönyvtárába.
karaigabor@karaigabor:~/downloads/matlab$ cd ../.. karaigabor@karaigabor:~$
A cd parancs önmagában a felhasználó saját home könyvtárába irányít.
karaigabor@karaigabor:~/downloads/matlab$ cd karaigabor@karaigabor:~$
'~': A felhasználó home könyvtárának elérési útvonalát tárolja.
karaigabor@karaigabor:~/downloads/matlab$ cd ~ karaigabor@karaigabor:~$
basename [kapcsolók] <útvonal>
(Kiegészítő anyag, nem lesz számonkérve!)
Kiírja a megadott útvonalban található könyvtárbejegyzés nevét szülőkönyvtárak nélkül, vagyis az utolsó, '/' utáni nemüres részt. Nem szükséges létező könyvtárbejegyzésre mutatnia a megadott útvonalnak. Csak paraméterben tud inputot fogadni, standard inputon nem!
karaigabor@karaigabor:~$ basename /alkonyvtar/konyvtar/fajl.kit fajl.kit karaigabor@karaigabor:~$ basename /alkonyvtar/allomany allomany karaigabor@karaigabor:~$ basename /alkonyvtar/konyvtar/ konyvtar
Kapcsolók:
-a <útvonalak>: Az összes felsorolt útvonalat feldolgozza a megadott sorrendben.
-s <utótag>: Az útvonal(ak) végéről eltávolítja az <utótag> szöveget, amennyiben arra végződik a bejegyzés. Használatakor nem szükséges megadni a -a kapcsolót több útvonal feldolgozásához.
karaigabor@karaigabor:~$ basename -s .txt /egy/ketto/harom.txt negy/ot.jpg hat/ het.mkv harom ot.jpg hat het.mkv karaigabor@karaigabor:~$ basename -s t /egy/ketto/harom.txt negy/ot.jpg hat/ het.mkv harom.tx ot.jpg hat het.mkv karaigabor@karaigabor:~$ basename -a /egy/ketto/harom.txt negy/ot hat/ het harom.txt ot hat het
dirname <útvonal>
(Kiegészítő anyag, nem lesz számonkérve!)
Kiírja a megadott útvonalból a könyvtárbejegyzés nevét megelőző részt, vagyis a szülőkönyvtárát. Ez általában az utolsó, '/' utáni nemüres rész levágását jelenti. Ha az útvonalban nem szerepel '/', a kimenet '.', míg a gyökérkönyvtárra önmagát adja kimenetként. Itt sem szükséges létező könyvtárbejegyzésre mutatnia a megadott útvonalnak. Csak paraméterben tud inputot fogadni, standard inputon nem! A basename paranccsal ellentétben kapcsoló nélkül is tetszőlegesen sok útvonal feldolgozására képes.
karaigabor@karaigabor:~$ dirname /egy/ketto/ XD.csv / konyvtar/alkonyvtar ./a/b/c/d.xml /egy . / konyvtar ./a/b/c
ls [kapcsolók] [könyvtár]
(list)
Kilistázza a megadott könyvtárban található könyvtárbejegyzéseket. A könyvtár megadása nélkül az aktuális könyvtár (munkakönyvtár) tartalmát írja ki. Alapértelmezés szerint ábécé sorrendben sorolja fel a neveket, de alkalmas kapcsolók segítségével más sorrendet és formátumot is előírhatunk.
Kiírja a "matlab" könyvtár tartalmát.
karaigabor@karaigabor:~/downloads/matlab$ ls
Kiírja a gyökérkönyvtár tartalmát.
karaigabor@karaigabor:~/downloads/matlab$ ls /
Néhány kapcsoló:
-1: Soronként egyetlen bejegyzés neve szerepel.
-a: A rejtett - azaz '.' karakterrel kezdődő - könyvtárbejegyzéseket is kilistázza.
-A: A rejtett könyvtárbejegyzéseket is kilistázza a "." és ".." kivételével.
-l: Oszlopokban, részletesen mutatja a bejegyzések adatait.
-g: Mint a -l, de kihagyja a tulajdonost.
-o: Mint a -l, de kihagyja a csoportnevet.
-h: Olvashatóbb formában írja ki a méretadatokat (pl. K -> kilobájt, M -> megabájt)
-S: Fájlméret szerint listáz, méghozzá csökkenő sorrendben.
-X: Kiterjesztés szerint listáz.
-R: Az alkönyvtárakat rekurzívan bejárja.
-r: Fordított sorrendben listáz.
Megjegyzés: a kapcsolókat lehet kombinálva is használni. Mindkét alábbi esetben kilistázza részletes adatokkal (-l) a rejtett könyvtárbejegyzésekkel együtt (-A), méghozzá ábécé szerint csökkenő sorrendben (-r).
karaigabor@karaigabor:~$ ls -l -a -r karaigabor@karaigabor:~$ ls -lar
find [útvonal] [kapcsolók]
(Kiegészítő anyag, nem lesz számonkérve!)
A FindUtils GNU programcsomag része. Könyvtárbejegyzéseket keres a megadott útvonalból kiindulva. Ha nem adunk meg útvonalat, az aktuális könyvtárból indítja a keresést. Rengeteg kapcsolóval rendelkezik, emellett operátorokat is használhatunk vele. Alapértelmezetten a rejtett állományokat is kilistázza, és az alkönyvtárakat is bejárja. Részletesebben lásd: man find.
Néhány kapcsoló:
-name <minta>: Szűrés név alapján. Csak a <minta>-ra illeszkedő névvel ellátott bejegyzéseket listázza ki.
-path <minta>: Szűrés útvonal alapján. Csak a <minta>-ra illeszkedő útvonallal rendelkező bejegyzéseket listázza ki.
-regex <regex>: Szűrés név alapján reguláris kifejezéssel.
-type <típus_azonosító>: Szűrés könyvtárbejegyzések típusa alapján.
A <típus_azonosító> lehetséges értékei közül a legfontosabbak: d: könyvtár, f: közönséges fájl (vagyis szabályos állomány), l: szimbólikus link
-size <[+-]méret>: Szűrés méret alapján. Alapértelmezetten csak a megadott méretű bejegyzéseket listázza ki. A '+' és '-' karakterekkel a megadottnál rendre nagyobb és kisebb bejegyzésekre szűr.
-atime <[+-]szám>: Szűrés utolsó módosítás ideje alapján. Csak a pontosan <szám> nappal (<szám>*24 órával) ezelőtt módosított bejegyzéseket listázza ki. A '+' és '-' karakterekkel rendre "több mint" és "kevesebb mint" <szám> nappal korábban módosított bejegyzésekre szűr.
-mindepth <szám>: A kiindulási ponttól számítva legalább <szám> mélységben keres.
-maxdepth <szám>: A kiindulási ponttól számítva legfeljebb <szám> mélységben keres. Ha ez az érték 1, nem keres az alkönyvtárakban.
Összes alkönyvtár listázása az aktuális mappából kiindulva.
karaigabor@karaigabor:/$ find -type d
A 240 bájtnál kisebb méretű fájlok listázása a felhasználó home könyvtárából.
karaigabor@karaigabor:/$ find ~ -maxdepth 1 -type f -size -240c
A /etc mappától számítva legalább 4 szinttel lejjebb található, legalább 2 nappal (48 órával) ezelőtt módosított fájlok listázása.
karaigabor@karaigabor:/$ find /etc -mindepth 4 -type f -atime +1
A negálás (!) láncolási operátorral ellentétes jelentést tulajdoníthatunk a soron következő szűrőfeltételnek. Az alábbi példa az összes nem rejtett fájlt listázza ki az aktuális könyvtárból.
karaigabor@karaigabor:~$ find -maxdepth 1 -type f ! -name '.*'
Megjegyzések:
A felsorolt bejegyzéseknek nem csak a nevét, hanem a relatív vagy abszolút útvonalát is kiírja a kiindulási útvonal típusával megegyező módon. Ha nem adunk meg kezdő könyvtárat, relatív címzést használ listázáskor.
Alkönyvtárak listázásakor a kiindulási könyvtárat is kiadja, méghozzá első elemként. Ez kiszűrhető például a -mindepth 1 feltétellel.
A globális szűrési beállításokat (mint a -mindepth és a -maxdepth, lásd man find) kell először megadni, különben figyelmeztető üzenetet kapunk.
Folyamatok leállítása
^C
A Ctrl+c billentyűparanccsal leállíthatunk előtérben futó folyamatokat.
Jogosultságok
Többfelhasználós rendszereken elengedhetetlen a különböző tartalmakhoz való hozzáférés szabályozása/korlátozása.
Linux operációs rendszereken háromféle engedély létezik a fájlrendszerben található könyvtárbejegyzésekre, melyek mindig egymástól függetlenül állíthatók:
- olvasás (r - read): Tartalom láthatóságát befolyásolja fájloknál és könyvtáraknál is.
- írás (w - write): Tartalom módosíthatóságát (szerkeszthetőségét és törölhetőségét) befolyásolja fájloknál és könyvtáraknál is. Utóbbinál meglévő könyvtárbejegyzések áthelyezéséhez, és újak létrehozásához is szükséges.
- futtatás (x - execute): Fájlok, tipikusan programfájlok (bináris vagy szkript) futtathatóságát befolyásolja. Könyvtáraknál az írási jog mellett feltétlenül szükséges a változtatásokhoz, ugyanis a részletes metaadatokhoz (pl. amiket az ls -l parancs szolgáltat) való hozzáférést szabályozza. Továbbá munkakönyvtárként is (pl. cd paranccsal) csupán ezen jog mellett használható.
A fenti három engedély három felhasználói kategóriára szabályozható minden könyvtárbejegyzésre:
- tulajdonos (u - user): Mindig pontosan egy felhasználó tölti be ezt a szerepet. Az új könyvtárbejegyzések létrehozója automatikus a tulajdonosa lesz. A root felhasználón kívül kizárólag ő módosíthatja a jogosultsági beállításokat.
- csoport (g - group): Legfeljebb egy felhasználói csoport tölti be ezt a szerepet, bár nem kötelező beállítani. Utóbbi esetben nincs (none) az értéke. Ráadásul nem kötelező olyan csoportot megadni, melynek tagja a tulajdonos.
- mindenki más (o - others): Az összes, az előző két kategória egyikébe sem tartozó felhasználó. Az új könyvtárbejegyzések létrehozója automatikus a tulajdonosa lesz.
Az elérési jogok megváltoztatására a chmod parancs szolgál, amely kétféle szintaxissal használható:
1. verzió: chmod [ugoa][+-][rwx] <útvonal>
Az [ugoa] betűkkel jelöljük azt a felhasználói kategóriát, amelyiknek változtatni szeretnénk az engedélyein. Az a betű mindenkinek egyszerre végzi el a módosítást. Utóbbi hatás ezen betű elhagyásával is elérhető. A [+-] azt jelenti, hogy adjuk (+) vagy elvesszük (-) a jogokat. Végül magát a jogot kell megnevezni.
karaigabor@karaigabor:~/Dokumentumok$ ls -l drwxrwxrwx 2 karaigabor karaigabor 4096 aug 9 15:07 hello karaigabor@karaigabor:~/Dokumentumok$ chmod g-w hello karaigabor@karaigabor:~/Dokumentumok$ ls -l drwxr-xrwx 2 karaigabor karaigabor 4096 aug 9 15:07 hello
2. verzió chmod <xxx> <útvonal>
Hasonló az előzőhöz, viszont itt minden x helyén 0-7-ig való osztályozással adható meg a különböző felhasználói kategória jogosultágai.
Rendre egy darab x helyettesítésének jelentése:
0: 000 --- semmi jog 1: 001 --x csak futtatási 2: 010 -w- csak írási 3: 011 -wx írási és futtatási 4: 100 r-- csak olvasási 5: 101 r-x olvasási és futtatási 6: 110 rw- olvasási és írási 7: 111 rwx olvasási, írási és futtatási jog
karaigabor@karaigabor:~/Dokumentumok$ ls -l drwx----wx 2 karaigabor karaigabor 4096 aug 9 15:07 hello karaigabor@karaigabor:~/Dokumentumok$ chmod 777 hello karaigabor@karaigabor:~/Dokumentumok$ ls -l drwxrwxrwx 2 karaigabor karaigabor 4096 aug 9 15:07 hello
Kapcsolók:
-R: rekurzívan az összes fájlra és alkönyvtárra elvégzi a beállítást.
Felhasználók kezelése
(Kiegészítő anyag, nem lesz számonkérve!)
finger [felhasználó]@node.domain
who
w
whoami
groups
passwd
chown <felhasználó> <útvonal>
chgrp <csoportnév> <útvonal>
Kiírja, hogy kik vannak bejelentkezve a megadott szerverre.
felhasználó: a megadott felhasználóról ír ki adatokat.
Kiírja, hogy kik vannak bejelentkezve az aktuális rendszerbe.
Hasonló a who-hoz, viszont a bejelentkezett felhasználók által előtérben futtatott folyamatokat is kilistázza.
Aktuális felhasználó azonosítójának kiírása.
Aktuális felhasználó csoportjának kiírása.
Aktuális felhasználó jelszavának beállítása.
Megváltoztatja az útvonalon található könyvtárbejegyzés tulajdonosát.
Megváltoztatja az útvonalon található könyvtárbejegyzéshez tartozó felhasználói csoportot.
cat parancs
(concat)
Általános alak: cat [kapcsolók] [fájl_1 …]
Fájlok tartalmát továbbítja a standard kimenetre. Paraméter nélkül a standard inputról olvassa be a szöveget. Ha több fájlt adunk meg, a felsorolás sorrendjében összefűzi a tartalmukat. Segítségével a standard bemeneten keresztül tudjuk biztosítani a fájlok tartalmát további feldolgozásra, valamint átirányítással kombinálva pár további trükköt is tud, lásd az átirányítások fejezetet.
Kapcsolók:
-n: Számozza a sorokat. Ekkor kicsit beljebb is húzza őket.
-b: Számozza a nemüres sorokat, ekkor is kicsit beljebb húzva őket.
-s: Az egymás után ismétlődő üres sorokból csak egyet őriz meg.
-E: A sorok végére '$' karaktert helyez kiíratáskor.
karaigabor@karaigabor:~$ cat memek.txt kettő;6;fél sör három;8;asztal de;nem szék Négy;1;egy sör; öt;10;Mi;folyik;itt;Gyöngyösön? karaigabor@karaigabor:~$ cat -nE memek.txt hallgatok.csv 1 kettő;6;fél sör$ 2 három;8;asztal de;nem szék$ 3 Négy;1;egy sör;$ 4 öt;10;Mi;folyik;itt;Gyöngyösön?$ 5 Név;Neptun kód;Szak;Kor;Évfolyam$ 6 Bela;EZMIEZ;PTI;18;1$ 7 Geza;KIVAGY;MI;20;2$ 8 Jonas;TUCS0K;PTI;25;1$ 9 Ede;XXEDXX;PTI;22;3$ 10 Dezso;NEKEM8;MI;21;2$
Átirányítások
Parancsok kiadásakor a bemeneti és kimeneti csatornák átirányítására is lehetőségünk van, ezzel megváltoztatva az alapértelmezett viselkedésüket attól függően, hogy mely csatornákat használják. Az átirányítást két fő csoportja oszthatjuk: bemenet (jellemzően stdin) és kimenet (jellemzően stdout vagy stderr). Alább részletezzük a legfontosabb átirányítás operátorokat, a teljes lista az online dokumentációban található.
parancs [n]< <fájl>
A parancs az n azonosítójú bemeneti csatornán keresztül kapja a fájl tartalmát - parancssori paraméter helyett. Ha n-et elhagyjuk vagy 0-t adunk meg, a standard inputra irányít át.
A tr parancs csak standard inputon fogad adatot, a wc parancs pedig kevesebb részlettel szolgál a standard bemeneten kapott szövegről. Mindkét parancsot az L2 anyagrészben tárgyaljuk.
karaigabor@karaigabor:~$ cat tomb_teszt everything is awesome EVERYTHING is cool everything is working OS is easy karaigabor@karaigabor:~$ tr -s ' ' < tomb_teszt.txt everything is awesome EVERYTHING is cool everything is working OS is easy karaigabor@karaigabor:~$ wc -c tomb_teszt.txt 92 tomb_teszt.txt karaigabor@karaigabor:~$ wc -c < tomb_teszt.txt 92
Megjegyzés: A cat <fájl> és a cat < <fájl> parancs hatása ugyanaz, amennyiben csak egy fájlt adunk meg.
parancs [n]> <fájl>
A parancs az n azonosítójú kimeneti csatornán keresztül továbbított eredményt a megadott fájlba menti. Ha a fájl már létezett, a korábbi tartalma elvész. Ha n-et elhagyjuk, a standard output csatornát irányítja át.
karaigabor@karaigabor:~$ ls -l > file.txt karaigabor@karaigabor:~$ cat file.txt -rw-r--r-- 1 karaigabor karaigabor 83 aug 9 21:01 file2.txt -rw-r--r-- 1 karaigabor karaigabor 0 aug 13 19:10 file.txt drwxr-xrwx 2 karaigabor karaigabor 4096 aug 9 15:07 hello -rw-r--r-- 1 karaigabor karaigabor 15796 aug 13 19:09 progalap_linux
Ha a cat parancsnak nem adunk fájl paramétert, és a kimenetét egy (akár már létező) fájlba irányítjuk át, közvetlenül a terminálon gépelhetünk szöveget az átirányított fájlba. A folyamatot a Ctrl+c billentyűkombinációval fejezhetjük be.
karaigabor@karaigabor:~$ cat > file.txt Új szöveg. A fájl tartalma felülíródik. ^C karaigabor@karaigabor:~$ cat file.txt Új szöveg. A fájl tartalma felülíródik.
Folyamatok kimeneti csatornáinak némítására használatos a /dev/null speciális fájl. Ez ugyanis minden beleírt adatot töröl, miközben az írási művelet sikeres. Ha létezik egy KaraiGabor futtatható állomány, annak standard kimenetét az alábbi módon elrejthetjük.
karaigabor@karaigabor:~/OpenGL$ ./KaraiGabor > /dev/null
Egyszerre mindkét kimeneti csatornát a &> fájl szintaxissal irányíthatjuk át. Az alábbi módszer már a program minden üzenetetét elrejti.
karaigabor@karaigabor:~/OpenGL$ ./KaraiGabor &> /dev/null
&n alakban másik kimeneti csatornára történhet az átirányítás. Például a >&2 a standard kimenetet a standard hibakimenetre irányítja át.
karaigabor@karaigabor:~/OpenGL$ ./KaraiGabor >&2
parancs [n]>> <fájl>
A parancs az n azonosítójú kimeneti csatornán keresztül továbbított eredményt a megadott fájl végéhez fűzi hozzá. Szintaxisa teljesen megegyezik a > operátorral.
karaigabor@karaigabor:~$ ls -1 >> file.txt karaigabor@karaigabor:~$ cat file.txt -rw-r--r-- 1 karaigabor karaigabor 83 aug 9 21:01 file2.txt -rw-r--r-- 1 karaigabor karaigabor 0 aug 13 19:10 file.txt drwxr-xrwx 2 karaigabor karaigabor 4096 aug 9 15:07 hello -rw-r--r-- 1 karaigabor karaigabor 15796 aug 13 19:09 progalap_linux file2.txt file.txt hello progalap_linux
Műveletek könyvtárbejegyzésekkel
(Kiegészítő anyag, nem lesz számonkérve!)
touch <fájl>
Új, tetszőleges kiterjesztésű fájlt létrehozhatunk vele.
karaigabor@karaigabor:~$ ls karaigabor@karaigabor:~$ touch vmi.txt akarmi karaigabor@karaigabor:~$ ls akarmi vmi.txt
Megjegyzés: A fő funkciója létező fájlok utolsó hozzáférési/módosítási időpontjának megváltoztatása.
mkdir [kapcsolók] <új mappa>
(make directory)
Új könyvtár létrehozására szolgál.
Egy "hello" nevű mappa létrehozása az aktuális könyvtárban.
karaigabor@karaigabor:~$ mkdir hello
Kapcsolók:
-p: Létrehozza a kívánt könyvtár eléréséig az összes szükséges könyvtárat.
karaigabor@karaigabor:~$ mkdir -p hello/hello2/hello3
-m <jogosultságok>: Megadhatjuk a könyvtárhoz való hozzáférési jogokat, méghozzá oktálisan.
karaigabor@karaigabor:~/hello$ mkdir -m 777 hello2 karaigabor@karaigabor:~/hello$ ls -l drwxrwxrwx 2 karaigabor karaigabor 4096 aug 5 17:05 hello2
rmdir [kapcsolók] <törlendő mappa>
(remove directory)
Üres könyvtárak törlésére szolgál.
Az alábbi parancs törli a "hello" nevű mappát.
karaigabor@karaigabor:~$ rmdir hello
Kapcsolók:
-p: A könyvtár törlése után, a szülő könyvtárat is törli rekurzívan, ha üressé válnak.
A felhasználó saját home könyvtárában található egy "hello" nevű mappa és azon belül egy "hello2" nevű mappa. Ha a felhasználó home könyvtára az aktuális könyvtár, akkor a "hello2" mappa -p kapcsoló megadásával történő törlése után a hello mappa is törlődni fog, mivel nem tartalmaz mást.
karaigabor@karaigabor:~$ mkdir -p hello/hello2 karaigabor@karaigabor:~$ rmdir -p hello/hello2
rm [kapcsolók] <törlendő bejegyzés>
(remove)
Kitörli a megadott könyvtárbejegyzéseket. Az alábbi parancs törli a file1.txt és a file2.txt fájlt a munkakönyvtárból.
karaigabor@karaigabor:~$ rm file1.txt file2.txt
Kapcsolók:
-d: Üres könyvtár törlése, mint az rmdir parancs esetében.
-f: Kényszerített törlés, sosem kérdez.
-i: Megerősítést kér minden egyes könyvtárbejegyzés törlése előtt.
-r, -R: könyvtár teljes tartalmának (rekurzív) törlése.
Törlésre kerül az elso/masodik mapparendszer annak ellenére, hogy nem üres.
karaigabor@karaigabor:~$ ls elso karaigabor@karaigabor:~$ cd elso/masodik karaigabor@karaigabor:~/elso/masodik$ ls t.txt karaigabor@karaigabor:~/elso/masodik$ cd ../.. karaigabor@karaigabor:~$ rm -r elso karaigabor@karaigabor:~$ ls karaigabor@karaigabor:~$
mv [kapcsolók] <forrás> <cél>
(move)
Könyvtárbejegyzések áthelyezésére szolgál. Ha nem adunk meg fájlnevet a célnál, akkor nem változik meg a neve, különben a megadott fájlnév lesz a célkönyvtárban.
Az alábbi parancs áthelyezi a "hello" nevű fájlt az aktuális (Dokumentumok) könyvtárból a Letöltések könyvtárba.
karaigabor@karaigabor:~/Dokumentumok$ mv hello /home/karaigabor/Letöltések
Kapcsolók:
-f: Kényszerített áthelyezés, nem kérdez felülírás előtt.
-i: Felülírás előtt kérdez.
-n: Nem ír felül létező fájlokat.
-u: Csak régebbit ír felül.
Állományok helyben történő átnevezésére is az mv parancsot használhatjuk.
karaigabor@karaigabor:~/Dokumentumok$ mv hello.txt hello2.txt
cp [kapcsolók] <forrás> <cél>
(copy)
Átmásolja a forrás fájlt a megadott helyre. Az alábbi parancs átmásolja az image.png fájlt a Letöltések könyvtárból a Dokumentumok könyvtárba.
karaigabor@karaigabor:~/Letöltések$ cp image.png /home/karaigabor/Dokumentumok
Kapcsolók:
-f: Kényszerített másolás, nem kérdez felülírás előtt.
-i: Felülírás előtt kérdez.
-n: Létező fájl felülírásának tiltása.
-r, -R: könyvtár teljes tartalmának másolása rekurzívan.
-u: Csak régebbit ír felül.
-l: Hard linkelés másolás helyett.
-s: Szimbólikus linkelés másolás helyett.
Pontosvessző (;) operátor
(Kiegészítő anyag, nem lesz számonkérve!)
Általános alak: parancs_1; parancs_2; … parancs_k
Több utasítás kötegelt végrehajtását teszi lehetővé, mintha egyetlen parancsot adnánk ki a terminálban. Az alábbi példában létrehozunk egy új könyvtárat az aktuális könyvtárban "ujmappa" néven, amelybe ezután belenavigálunk, végül kiíratjuk a munkakönyvtár elérési útvonalát.
karaigabor@karaigabor:~$ mkdir ujmappa; cd ujmappa; pwd /home/karaigabor/ujmappa karaigabor@karaigabor:~/ujmappa$
Backslash (\) operátor
Parancsok tördelése
Ha egy parancs szövege túl hosszú lenne, tördeléssel olvashatóbbá tehető vele. Sortörés beillesztése (Enter leütése) után az előző sorban megkezdett parancs szövegét folytathatjuk.
karaigabor@karaigabor:~$ find -mindepth 2 -maxdepth 5 \ > -type f -name "*fajl*.txt"
A fenti parancs az alábbival egyenértékű:
karaigabor@karaigabor:~$ find -mindepth 2 -maxdepth 5 -type f -name "*fajl*.txt"
Speciális karakterek escape-elése
Operátorként funkcionáló karakterek speciális jelentésének elvételére is használható, így a karakter egy tényleges példánya kerül beillesztésre.
karaigabor@karaigabor:~$ echo szöveg\(1\) szöveg\\n szöveg(1) szöveg\n
L2
Linkelés
(Kiegészítő anyag, nem lesz számonkérve!)
ln [kapcsolók] <forrás> <cél>
Hard link
A linkelés arra szolgál, hogy egy könyvtárbejegyzést több útvonalon is el lehessen érni a fájlrendszerben további fizikai példányok lérehozása (másolás) nélkül. Kétféle link létezik, ezek a hard link (merev lánc) és a soft link (szimbólikus link vagy szimbólikus lánc). Mindkettő az ln paranccsal hozható létre. A két link típus közötti különbséget ez az ábra szemlélteti.
(link)
Az első paraméter az a bejegyzés, amihez szeretnénk linket készíteni, a második paraméter a létrehozandó link útvonala. Kapcsoló nélkül hard linket készít.
Kapcsolók:
-s: Szimbólikus (soft) link készítése.
Közvetlenül az adott állomány inode-tábla bejegyzésére mutat, ezáltal az eredeti állomány fizikai címére hivatkozik. A hivatkozott tartalomnak azonos partíción, fizikai vagy virtuális eszközön kell lennie. Ráadásul könyvtárra nem lehet hard linket létrehozni, mivel az önmagában tartalom helyett csupán szerkezeti információt takar.
Létrehozunk egy file.txt fájlt, melybe a "hello" szöveget írjuk. Ezután készítünk egy hard linket a fájlunkra hard_link néven. Majd módosítjuk a fájlt, amelynek eredményeképpen a hard_link is módosul. Így mindkét fájlban a "Hello\nworld!" szöveg fog szerepelni. Listázásnál a második mező jelenti a fájlra mutató hard linkek számát. Ha kitöröljük az egyik fájlt, attól a másik még használható.
karaigabor@karaigabor:~$ cat > file.txt Hello ^C karaigabor@karaigabor:~$ ln file.txt hard_link karaigabor@karaigabor:~$ ls -l -rw-r--r-- 2 karaigabor karaigabor 6 aug 7 01:15 file.txt -rw-r--r-- 2 karaigabor karaigabor 6 aug 7 01:15 hard_link karaigabor@karaigabor:~$ cat >> file.txt world! ^C karaigabor@karaigabor:~$ cat hard_link Hello world!
Soft (Szimbólikus) link:
A szimbólikus link egy önálló fájltípus, mely a hivatkozott könyvtárbejegyzés (jellemzően abszolút) útvonalát tartalmazza. A hard linkkel szemben tetszőleges helyre hivatkozhatunk a fájlrendszerben (akár könyvtárra is). Nem tévesztendő össze a Windows rendszereken gyakran haszált parancsikonnal, az ugyanis egy közönséges, lnk kiterjesztésű állománynak számít.
A meglévő file.txt fájlunkhoz szimbólikus linket készítünk. Listázás után ez jól megfigyelhető az elkészült soft_link után látható nyíl alapján, amely a file.txt-re mutat. Amennyiben töröljük a txt fájlt, akkor a link használhatatlan lesz, mivel töröltük a hivatkozott fájlt.
karaigabor@karaigabor:~$ ln -s file.txt soft_link karaigabor@karaigabor:~$ ls -l -rw-r--r-- 2 karaigabor karaigabor 13 aug 7 01:16 file.txt -rw-r--r-- 2 karaigabor karaigabor 13 aug 7 01:16 hard_link lrwxrwxrwx 1 karaigabor karaigabor 9 aug 7 01:29 soft_link -> file.txt karaigabor@karaigabor:~$ rm file.txt karaigabor@karaigabor:~$ ls -l -rw-r--r-- 1 karaigabor karaigabor 29 aug 7 01:34 hard_link lrwxrwxrwx 1 karaigabor karaigabor 9 aug 7 01:29 soft_link -> file.txt
Szöveg kiíratása
echo [szöveg lista]
A paraméterben megadott - egymástól szóközzel elválasztott - szövegeket írja ki a képernyőre. Ha az egész szöveget idézőjelek - azaz aposztrófok (') vagy macskakörmök (") közé tesszük, akkor azt egyetlen paraméterként értelmezi.
Kapcsolók:
-n: Nem dob új sort a kiíratás után.
-e: Értelmezi az escape szekvenciákat (\n, \t, …). Használatuk esetén mindenképpen idézőjelek közé kell tenni a kiírandó szöveget.
karaigabor@karaigabor:~$ echo Hello Kitty! Hello Kitty! karaigabor@karaigabor:~$ echo 'Hello\tKitty!' Hello\tKitty! karaigabor@karaigabor:~$ echo -e 'Hello\tKitty!' Hello Kitty!
Konstans szövegeket - vagyis a sztring literálokat - általában nem szükséges idézőjelek közé tenni, mert a BASH alapértelmezetten úgy kezeli őket. Aposztrófok között is konstans szöveget feltételez a BASH. A macskakörömnek szövegbe ágyazott utasítások és változók kezelésekor van fontos szerepe, amit a B1 anyagrészben tárgyalunk.
printf <formátumsztring> [paraméter lista]
(Kiegészítő anyag, nem lesz számonkérve!)
Formázott szöveg kiíratására szolgál. A helyes működéshez a formátumsztringet idézőjelek közé kell tenni, ami lehet macskaköröm (" ") vagy aposztróf (' ') is.
karaigabor@karaigabor:~$ printf "132 hexadecimálisan: %x\n" 132 132 hexadecimálisan: 84
Néhány dologban eltér a használata a C-ben megismert változathoz képest. Az alábbi példa a '+' karakter ASCII kódját írja ki.
karaigabor@karaigabor:~$ printf "A '+' karakterkódja: %d\n" "'+" A '+' karakterkódja: 43
Szöveges fájlok kezelése (1. rész)
head [kapcsolók] <fájl>
Kiírja a fájl első néhány sorát/bájtját, alapértelmezetten az első 10 sorát.
Kapcsolók:
-n <szám>: Az első <szám> darab sort írja ki. Nem hivatalos rövidebb alakja a -<szám>.
-n -<szám>: Kiírja a fájl tartalmát, kivéve az utolsó <szám> darab sort.
-c <szám>: Az első <szám> darab bájtot írja ki.
-c -<szám>: Kiírja a fájl tartalmát, kivéve az utolsó <szám> darab bájtot, beleszámítva a sortörés karaktereket is.
karaigabor@karaigabor:~$ cat ekezetes_sorszamok.txt első második harmadik negyedik ötödik hatodik hetedik nyolcadik kilencedik tizedik karaigabor@karaigabor:~$ head -n 4 ekezetes_sorszamok.txt első második harmadik negyedik karaigabor@karaigabor:~$ head -n -4 ekezetes_sorszamok.txt első második harmadik negyedik ötödik hatodik karaigabor@karaigabor:~$ head -c 9 ekezetes_sorszamok.txt első má
A helyes működéshez a -c kapcsoló használatakor – UTF-8 kódolással – több bájton tárolt karakterekből nem szabad levágni egyetlen bájtot sem!! Ilyenek például a magyar ábécé ékezetes magánhangzói. Ha ezt figyelmen kívül hagyjuk, érvénytelen karakterhez juthatunk, mely az alábbi példában is látható.
karaigabor@karaigabor:~$ head -c 4 file2.txt els�
tail [kapcsolók] <fájl>
Kiírja a fájl utolsó néhány sorát/bájtját, alapértelmezetten az utolsó 10 sorát.
Kapcsolók:
-n <szám>: Az utolsó <szám> darab sort írja ki. Nem hivatalos rövidebb alakja a -<szám>.
-n +<szám>: A <szám>-adik sortól kezdve ír ki.
-c <szám>: Az utolsó <szám> darab bájtot írja ki.
-c +<szám>: A <szám>-adik bájttól kezdve ír ki.
karaigabor@karaigabor:~$ tail -n 3 ekezetes_sorszamok.txt nyolcadik kilencedik tizedik karaigabor@karaigabor:~$ tail -n +5 ekezetes_sorszamok.txt ötödik hatodik hetedik nyolcadik kilencedik tizedik karaigabor@karaigabor:~$ tail -c 11 ekezetes_sorszamok.txt ik tizedik
A head parancshoz hasonlóan itt is figyelni kell a -c kapcsoló használatakor a több-bájtos karakterekre!
karaigabor@karaigabor:~$ tail -c 50 ekezetes_sorszamok.txt �dik hatodik hetedik nyolcadik kilencedik tizedik
Csővezeték (Pipeline)
Általános alak: parancs_1 | parancs_2 | … | parancs_k
Az egyik láncolási operátor. parancs_(n-1) által a standard kimenetre küldött szöveg parancs_n a standard bemeneten kapja meg. Így például a head és tail parancs kombinálásával szöveges fájlok tartalmának vagy parancsok kimenetének tetszőleges sortartományára szűrhetünk.
karaigabor@karaigabor:~$ cat sorszamok.txt elso masodik harmadik negyedik otodik hatodik hetedik nyolcadik kilencedik tizedik karaigabor@karaigabor:~$ head -n 9 sorszamok.txt | tail -n 3 hetedik nyolcadik kilencedik karaigabor@karaigabor:~$ tail -n +7 sorszamok.txt | head -n 3 hetedik nyolcadik kilencedik karaigabor@karaigabor:~$ ls -1 sorszamok.txt gyakjegyzet.pdf hello.awk otos.csv peldatar.pdf karaigabor@karaigabor:~$ ls -1 | head -n 4 | tail -n +3 hello.awk otos.csv
Nem minden parancs fogad bemenetet a standard inputról, ezek nem használhatók csővezeték nemelső elemeként. Ilyen például a basename és a dirname parancs.
Szöveges fájlok kezelése (2. rész)
tr
(translate)
Karakterek lecserélése, tömörítése és/vagy törlése. Előbbi műveletre az általános alak:
tr <forrás karakterhalmaz> <cél karakterhalmaz>
Például az alábbi parancs nagybetűsíti a megadott szöveget:
karaigabor@karaigabor:~$ echo "Operacios Rendszerek" | tr a-z A-Z OPERACIOS RENDSZEREK
Az előző példa csak az angol ábécé kisbetűit cseréli nagybetűre, mert az "a-z" kifejtve "abcdefghijklmnopqrstuvwxyz". Az ékezetes betűket egyesével kell felsorolnunk.
karaigabor@karaigabor:~$ echo "Operációs Rendszerek" | tr a-záéíóöőúüű A-ZÁÉÍÓÖŐÚÜŰ OPERÁCIÓS RENDSZEREK
A helyes működéshez csak (UTF-8 kódolással) ugyanannyi bájton ábrázolt kicserélendő karakterpárokat használjunk! Például ne keverjük az angol magánhangzókat (1 bájtos karakterek) magyar ékezetes magánhangzókkal (2 bájton ábrázolt karakterek), lásd az UTF-8 karaktertáblát!
Ha a célhalmaz hosszabb, a forráshalmaz hosszánál nagyobb indexű karaktereket figyelmen kívül hagyja. Viszont ha a forráshalmaz hosszabb, a célhalmaz hosszánál nagyobb indexű karaktereket a célhalmaz utolsó karakterére cseréli.
karaigabor@karaigabor:~$ echo h987654 | tr 4-9 x hxxxxxx karaigabor@karaigabor:~$ echo h987654 | tr 4-9 xyz hzzzzyx
Kapcsolók:
-s <karakterhalmaz>: A felsorolt karakterek egymás után ismétlődését egyetlen előfordulásra cseréli.
-d <karakterhalmaz>: Törli a felsorolt karakterek összes előfordulását.
karaigabor@karaigabor:~$ echo "Operációs Rendszerek gyakorlat" | tr -s " " Operációs Rendszerek gyakorlat karaigabor@karaigabor:~$ echo "Operációs Rendszerek gyakorlat" | tr -d sr Opeáció Rendzeek gyakolat
sort [kapcsolók] <fájl>
A fájl sorait ábécé szerint - azaz lexikografikusan - növekvő sorrendbe rendezve írja ki.
Kapcsolók:
-b: Figyelmen kívül hagyja a sor eleji whitespace karaktereket (pl. szóköz, vízszintes tabulátor).
-f: A kis- és nagybetűket azonosnak tekinti.
-n: Számok alapján (numerikusan) rendez.
-r: Csökkenő sorrendbe rendez.
-R: Összekeveri, véletlen sorrendbe rendezi a sorokat.
-k <mező_index[.karakter_index]>: Soron belül a megadott pozíciójú karaktertől és/vagy mezőtől kezdődően veszi figyelembe a sort.
-t <karakter>: Mezőelválasztó karakter megadása. Akkor hasznos, ha nem a sor első karaktere/mezője vagy k. szava alapján szeretnénk rendezni.
-u: A rendezést követően hátramaradt ismétlődő sorokat csak egyszer írja ki.
karaigabor@karaigabor:~$ cat sorszamok2.csv elso;3 masodik;6 harmadik;8 Negyedik;1 otodik;10 hatodik;5 Hetedik;4 nyolcadik;9 kilencedik;7 tizedik;2
Rendezzük a sorait a kis- és nagybetűk megkülönböztetése nélkül!
karaigabor@karaigabor:~$ sort -f sorszamok2.csv elso;3 harmadik;8 hatodik;5 Hetedik;4 kilencedik;7 masodik;6 Negyedik;1 nyolcadik;9 otodik;10 tizedik;2
Rendezzük a sorait az első két karakter figyelmen kívül hagyásával!
karaigabor@karaigabor:~$ sort -k 1.3 sorszamok2.csv Negyedik;1 kilencedik;7 otodik;10 nyolcadik;9 harmadik;8 elso;3 masodik;6 Hetedik;4 hatodik;5 tizedik;2
Rendezzük a sorokat a pontosvesszővel elválasztott második mező alapján, méghozzá numerikusan!
karaigabor@karaigabor:~$ sort -t ';' -k 2 -n sorszamok2.csv Negyedik;1 tizedik;2 elso;3 Hetedik;4 hatodik;5 masodik;6 kilencedik;7 harmadik;8 nyolcadik;9 otodik;10
uniq [kapcsolók] <fájl>
Az egymás után ismétlődő sorokat csak egyszer írja ki.
Kapcsolók:
-c: A sorok előfordulásának darabszámát is kiírja. Ekkor jellemzően sor eleji szóközöket is elhelyez, ezek eltávolíthatók például a sed 's/^ *//' paranccsal.
-i: A kis- és nagybetűket azonosnak tekinti.
-d: Csak az egymás után többször előforduló sorokat írja ki.
-D: Csak az egymás után ismétlődő sorokat írja ki, ráadásul az összes előfordulásukat.
-u: Csak az egymás után nem ismétlődő sorokat írja ki.
-s <szám>: A sorok első <szám> darab karakterét átugorja az összehasonlítás előtt.
-w <szám>: A soroknak legfeljebb <szám> darab karakterét hasonlítja össze.
karaigabor@karaigabor:~$ cat nevek.txt geza bela bela bela jonas jonas bela karaigabor@karaigabor:~$ uniq nevek.txt geza bela jonas bela karaigabor@karaigabor:~$ uniq -c nevek.txt 1 geza 3 bela 2 jonas 1 bela karaigabor@karaigabor:~$ uniq -d nevek.txt bela jonas karaigabor@karaigabor:~$ uniq -c -s 3 nevek.txt 4 geza 2 jonas 1 bela
Ha nem csak az egymás után ismétlődő sorokat szeretnénk kiszűrni, a rendezett sorokon kell végrehajtani a uniq parancsot, tehát sort <fájlnév> | uniq. Ez a művelet a sort -u <fájl> paranccsal is megvalósítható.
karaigabor@karaigabor:~$ sort nevek.txt | uniq bela geza jonas karaigabor@karaigabor:~$ sort -u nevek.txt bela geza jonas
cut <kapcsolók> <fájl>
Sorok kiválasztott bájtjait/karaktereit/mezőit (oszlopait) írja ki.
Kapcsolók:
-b <tartomány>: Soronként csak a <tartomány>-ba eső indexű bájtokat írja ki.
-c <tartomány>: Soronként csak a <tartomány>-ba eső indexű karaktereket írja ki.
-d <karakter>: Mezőelválasztó karakter megadása. Csak mezőkre szűrés esetén, vagyis a -f kapcsolóval együtt van értelme. Kizárólag egyetlen karakterből állhat!
-f <tartomány>: Soronként csak a <tartomány>-ba eső indexű mezőket írja ki.
<tartomány> lehet egyetlen szám, vesszővel elválasztott számok vagy intervallum (pl. 2-4; 6-). Az indexek csak növekvő sorrendben sorolhatók fel!
karaigabor@karaigabor:~$ cat memek.txt kettő;6;fél sör három;8;asztal de;nem szék Négy;1;egy sör; öt;10;Mi;folyik;itt;Gyöngyösön?
A több-bájtos karakterek helyes kiíratása érdekében nem szabad levágni egyetlen bájtot sem belőlük!
karaigabor@karaigabor:~$ cut -b 1,2 memek.txt ke h� N� ö karaigabor@karaigabor:~$ cut -b 7-12 memek.txt ;6;fé ;8;asz 1;egy ;Mi;fo
Az előbbi probléma karakterek kiválasztásakor nem áll fenn, így az ékezetes betűket is mindig sikeresen kiírja. Vágjuk le minden sorból az első 11 karaktert!
karaigabor@karaigabor:~$ cut -c 12- memek.txt sör tal de;nem szék sör; lyik;itt;Gyöngyösön?
Válogassuk ki pontosvessző mentén elválasztva az 1., 2. és 4. mezőt! Nem létező mezőre/bájtra/karakterre hivatkozás esetén nem ír ki semmit, még hibaüzenetet sem.
karaigabor@karaigabor:~$ cut -d ';' -f 1-2,4 memek.txt kettő;6 három;8;nem szék Négy;1; öt;10;folyik
wc [kapcsolók] <fájl>
Kiírja a fájl sorainak a számát, szavainak a számát, a bájtok számát és a fájl nevét.
Kapcsolók:
-l: Csak a nevet és a sorok - pontosabban sortörés karakterek - darabszámát írja ki.
-w: Csak a nevet és a szavak darabszámát írja ki.
-c: Csak a nevet és a bájtok darabszámát írja ki.
-m: Csak a nevet és a karakterek darabszámát írja ki.
karaigabor@karaigabor:~$ cat ekezetes_szamok.csv egy;3 kettő;6 három;8 Négy;1 öt;10 hat;5 Hét;4 nyolc;9 kilenc;7 tíz;2 karaigabor@karaigabor:~$ wc ekezetes_szamok.csv 10 10 76 ekezetes_szamok.csv karaigabor@karaigabor:~$ wc -w ekezetes_szamok.csv 10 ekezetes_szamok.csv
Ha csupán a megfelelő darabszámot szeretnénk kiíratni, átirányítással vagy csővezetékkel megtehetjük.
karaigabor@karaigabor:~$ wc -m < ekezetes_szamok.csv 70 karaigabor@karaigabor:~$ wc -m ekezetes_szamok.csv | cut -d ' ' -f 1 70 karaigabor@karaigabor:~$ cat ekezetes_szamok.csv | wc -m 70
Vegyük észre, hogy a ekezetes_szamok.csv fájlban eltér a bájtok száma a karakterek számától! Ez a 6 darab ékezetes betű miatt van, melyek egyenként 2-2 bájtot foglalnak.
sed parancs
(Kiegészítő anyag, nem lesz számonkérve!)
sed [kapcsolók] <parancsok> <fájl>
(stream editor)
Széles funkcionalitású szövegfeldolgozó (folyamszerkesztő) program, mely a megadott parancsokat lefuttatja a paraméterben kapott fájl(ok)on, alapértelmezetten soronként. Saját utasításkészlettel rendelkezik - lásd a POSIX szabványt és a GNU online dokumentációt -, melyekkel sokféle művelet hajtható végre. Néhány példa:
1. Karakterek összes előfordulásának kicserélése, mint a tr parancsnál, csak itt a forrás- és célhalmaz méretének szigorúan egyeznie kell. A tr paranccsal ellentétben a cserélendő karakterpároknak nem szükséges azonos bájtméretűnek lennie, ennek köszönhetően képes például az ékezetes magánhangzókat az ékezet nélküli párjukra cserélni.
karaigabor@karaigabor:~$ cat ekezetes_szamok.csv egy;3 kettő;6 három;8 Négy;1 öt;10 hat;5 Hét;4 nyolc;9 kilenc;7 tíz;2 karaigabor@karaigabor:~$ sed y/áéíóöőúüű/aeiooouuu/ ekezetes_szamok.csv egy;3 ketto;6 harom;8 Negy;1 ot;10 hat;5 Het;4 nyolc;9 kilenc;7 tiz;2
2. Sortartományra szűrés, mint a head és tail parancsok kombinálásánál. Az alábbi parancs csak a 3.-7. sorokat írja ki.
karaigabor@karaigabor:~$ sed -n 3,7p sorszamok2.csv harmadik;8 Negyedik;1 otodik;10 hatodik;5 Hetedik;4
3. Sortartomány törlése/kihagyása, amely az előző művelet szöges ellentéte. Az alábbi parancs átugorja a 3.-7. sorokat.
karaigabor@karaigabor:~$ sed 3,7d sorszamok2.csv elso;3 masodik;6 nyolcadik;11 kilencedik;7 tizedik;2 tizenegyedik;9
4. Keresett szövegrészlet kicserélése reguláris kifejezés segítségével, amely az egyik legnépszerűbb funkciója. Az alábbi parancs az "edik" sztring minden előfordulását "ÚJSZTRING"-re cseréli. A parancs végén található 'g' (global) kapcsoló nélkül minden sorban csak az első előfordulást cserélné ki. Mivel a tesztfájl minden sorában legfeljebb egy illeszkedés van, nincs hatása a 'g' kapcsolónak.
karaigabor@karaigabor:~$ sed 's/edik/ÚJSZTRING/g' sorszamok2.csv elso;3 masodik;6 harmadik;8 NegyÚJSZTRING;1 otodik;10 hatodik;5 HetÚJSZTRING;4 nyolcadik;9 kilencÚJSZTRING;7 tizÚJSZTRING;2
Mintaillesztés
Ha nem tudjuk egy szöveg pontos alakját, csak egy részét, vagy több könyvtárbejegyzésen szeretnénk egyszerre ugyanazt a műveletet végrehajtani, akkor jön jól a mintaillesztés. Használható például keresésre vagy egyszerre több fájl másolására, áthelyezésére, törlésére.
Speciális kifejezések:
?: Pontosan egy karaktert helyettesít. Például ?lma lehet alma vagy álma is - többek között.
*: Bármennyi (akár 0) karaktert helyettesít. Például *gép lehet gép, mosógép, számítógép, stb.
[HALMAZ]: A felsorolt karakterekből pontosan egyet helyettesít. Például [aó]lom lehet ólom vagy alom, fajl[034] pedig fajl0, fajl3 vagy fajl4.
[^HALMAZ]: Pontosan egy karaktert helyettesít a halmazban NEM szereplő karakterek közül.
[TÓL-IG]: Pontosan egy karaktert helyettesít a tartomány által lefedett karakterek közül. A TÓL-IG kifejezés a TÓL és IG (ASCII) karakterkódja közötti karakterkódú betűket/szimbólumokat helyettesíti be, ahogy a tr parancsnál is.
Az összes txt kiterjesztésű fájl kilistázása az aktuális könyvtárból.
karaigabor@karaigabor:~$ ls -a *.txt
Kicsit másképpen.
karaigabor@karaigabor:~$ find -maxdepth 1 -name "*.txt"
Minden png fájl átmásolása a Dokumentumok/kepek mappába.
karaigabor@karaigabor:~$ cp *.png Dokumentumok/kepek
Az összes kétkarakteres png képfájl törlése az aktuális könyvtárból.
karaigabor@karaigabor:~/Dokumentumok/kepek$ rm ??.png
Azon könyvtárbejegyzések kilistázása az aktuális könyvtárból, melyek neve egyetlen karakterből áll, s az nem számjegy.
karaigabor@karaigabor:~/Dokumentumok/kepek$ ls [^0-9].*
grep [kapcsolók] [minta] <fájl>
A szöveges bemenet azon sorait írja csak ki, amelyek illeszkednek a mintára, mint reguláris kifejezésre, lásd a POSIX szabványt és a GNU online dokumentációt. Tegyük aposztrófok (') közé az illesztett kifejezést!
Kapcsolók:
-E: A mintát kiterjesztett reguláris kifejezésként értelmezi. A grep -E parancs rövidebb alakja: egrep
-F: A mintát közönséges sztringként értelmezi. Leginkább a regexek speciális karaktereire illesztéskor hasznos. A grep -F parancs rövidebb alakja: fgrep
-c: Az illeszkedő sorok tartalma helyett csak azok darabszáma jelenik meg.
-n: Az illeszkedő sorok sorazonosítóját is kiírja.
-v: Az illeszkedés tiltása (negálás).
-e <minta>: Több minta megadásakor használandó. Ekkor legalább az egyik mintára való illeszkedést követeljük meg.
-r, -R: Könyvtárban szereplő fájlok feldolgozása rekurzívan.
karaigabor@karaigabor:~$ cat sorszamok.txt elso masodik harmadik negyedik otodik hatodik hetedik nyolcadik kilencedik tizedik karaigabor@karaigabor:~$ grep 'ed' sorszamok.txt negyedik hetedik kilencedik tizedik karaigabor@karaigabor:~$ grep -v 'ed' sorszamok.txt elso masodik harmadik otodik hatodik nyolcadik karaigabor@karaigabor:~$ grep -c -v 'ed' sorszamok.txt 6 karaigabor@karaigabor:~$ grep -e 'so' -e 'to' sorszamok.txt elso masodik otodik hatodik
Feladatok
1. Írj csővezetéket, amely kiírja a hallgatok.csv fájlban található különböző szakok darabszámát! A fájl első sora fejléc, ezt hagyd ki a feldolgozásból!
Elvárt kimenet: 2
2. Írj csővezetéket, amely megszámolja az ls-l.txt fájlban azokat a könyvtárbejegyzéseket, melyekre legalább az egyik joggal nem rendelkezik a tulajdonos! Ez azt jelenti, hogy a rá vonatkozó jogosultság hármasban (rwx) legalább egy '-' szerepel.
Elvárt kimenet: 11
További gyakorlófeladatok
Figyelem! Az alábbi feladatsorok a 2020-as anyagrészhez vannak igazítva, akkor készült a videósorozat is. Az aktuális anyagot nem fedik le teljesen!
Cservenák Bencétől és Kolozsi Istvántól: feladatlap, tesztfájl és egy lehetséges megoldás
Madarász Mátétól: feladatlap, tesztfájlok és egy lehetséges megoldás
B1
Bash szkriptfájlok felépítése
Fájlformátum, használat
A BASH szkript fájlok kiterjesztése .sh lesz. Terminálban a touch paranccsal, vagy akár átirányítással is létrehozhatjuk őket. A létrehozást követően a terminálból is megnyithatjuk őket egy általunk választott forráskódszerkesztőben.
Tegyünk a parancs végére "ÉS" (&) operátort annak érdekében, hogy a forráskódszerkesztő program ne foglalja le a promptot az alkalmazás bezárásáig! Ennek hatására ugyanis háttérfolyamatként indul el a program, így további utasításokat is ki tudunk adni a terminálban.
karaigabor@karaigabor:~$ touch szkript.sh karaigabor@karaigabor:~$ gedit szkript.sh & [1] 1745 karaigabor@karaigabor:~$ notepad++ szkript.sh & [2] 1748
Szögletes zárójelek között a felhasználó által háttérben indított folyamatok száma íródik ki, a mellette lévő szám pedig a folyamat (processzus) azonosítója. Ezeket a ps paranccsal listázhatjuk ki.
A futtatást és paraméterezést az alábbi módon fogjuk megejteni.
./fájlnév.sh [param1 param2 …]
Előbbi parancs az alábbi utasítással ekvivalens:
bash fájlnév.sh [param1 param2 …]
Fejléc: She-bang/Hash-bang
A szkriptet interpretáló program abszolút elérési útvonalát tartalmazza, méghozzá a "#!" sztringet követően. Mivel Bash szkripteket írunk, a Bash program elérési útvonalát kell megadnunk, amely rögzített.
#!/bin/bash
Közvetlenül a "#!" után opcionálisan szerepelhetnek elválasztó karakterek (szóköz, vízszintes tabulátor), de az elérési útvonalban NEM!
Megjegyzés
Egysoros: amennyiben nem határolójelek között van, a '#' után írt karaktereket az aktuális sorban figyelmen kívül hagyja az értelmező.
# példa egysoros megjegyzésre
Többsoros: a ':' utasítás minden paraméterét átugorja, ezáltal egy utána írt, több sorba tördelt sztringgel oldható meg.
: '
példa
többsoros
megjegyzésre
'
Változók
Használat
BASH-ben a változónevek csak az angol ábécé betűiből, számjegyekből és aláhúzásjelből állhatnak, és nem kezdődhet számmal. A kis- és nagybetűk különbözőnek számítanak változóneveknél is. A változóérték behelyettesítésekor a név elé egy $ karaktert írunk. Sztringek összefűzésekor - amennyiben közvetlenül a kifejezés után betű, számjegy vagy aláhúzásjel szerepel - { és } karakterek közé kell tennünk a változónevet, mert így tudja az értelmező megkülönböztetni a változónevet a sztring literáltól. Nagyon fontos, hogy értékadáskor NEM lehet helyköz az egyenlőségjel bal és jobb oldalán sem!
#!/bin/bash
val1="kecske"
val2="sajt"
echo $val1
echo $val1$val2
echo $val1${val2}os
A kiírott szöveg:
kecske kecskesajt kecskesajtos
Életciklus
(Kiegészítő anyag, nem lesz számonkérve!)
Szkriptnyelveknél bevált tendencia, hogy a változók első használatkor (jellemzően értékadással) automatikusan létrejönnek, a futás befejezésekor pedig törlődnek. A BASH változóknak szigorú értelemben nincs típusa, helyette attribútumo(ka)t rendelhetünk hozzájuk, amivel specifikálhatjuk a használatukat. Ha BASH-ben felül szeretnénk bírálni az alapértelmezett viselkedést, akkor a declare paranccsal expliciten kell létrehozni az adott változót. A program befejezése előtt pedig az unset paranccsal törölhetünk változókat.
declare [kapcsolók] [NÉV_1[=érték_1] …]
unset [kapcsolók] <NÉV>
Kapcsolók:
-i: Csak egész szám tárolását teszi lehetővé.
-l: Az értékül adott sztringben minden nagybetűt automatikusan kisbetűsít.
-u: Az értékül adott sztringben minden kisbetűt automatikusan nagybetűsít.
-r: A változó csak olvasható lesz, vagyis a létrehozásakor kapott kezdőértéke nem módosítható, valamint az unset paranccsal sem törölhető.
-n: Referencia változót hoz létre, vagyis az értékét változónévnek tekinti, és minden műveletet a hivatkozott változón fog végrehajtani.
-p: Kiírja a felsorolt változók attribútumait, paraméter nélkül pedig az összes változóét.
A fenti kapcsolók közül a -p kivételével mindegyik attribútum beállítást is végez. Létező változók attribútumának eltávolítása ugyanígy történik, csupán a kapcsolóban a '-' karaktert '+' karakterre kell cserélni.
Kapcsolók:
-v: A paramétert változónévnek tekinti.
-f: A paramétert függvénynévnek tekinti.
-n: Referencia változót szüntet meg, de az általa hivatkozott változót nem.
Kapcsolók nélkül változót próbál meg törölni a megadott névvel, és ha ez nem sikerül, akkor függvényt. Nem dob hibát, ha a kapott néven nem létezik változó és függvény sem.
szoveg="TeszTELésre_sz8LGÁló-SzövEG!"
declare -l kisbetus=$szoveg
declare -u nagybetus=$szoveg
echo "kisbetus: $kisbetus"
echo "nagybetus: $nagybetus"
A kiírott szöveg:
kisbetus: tesztelésre_sz8lgáló-szöveg! nagybetus: TESZTELÉSRE_SZ8LGÁLÓ-SZÖVEG!
declare -r konstans="szöveg"
konstans=0 # Hiba! Nem módosítható a csak olvasható változó értéke.
unset konstans # Hiba! A csak olvasható változó nem törölhető.
declare -i egesz
egesz=-19 # OK!
egesz=12valami # Hiba! Ha számot szöveg követ, nem tud vele mit kezdeni.
egesz="valami" # Ha egyáltalán nincs számjegy a kapott sztringben, a változó értéke 0 lesz.
Sztring műveletek
A ${NÉV} alak nem csak összefűzésre használható, ugyanis számos változóművelet ebből a formátumból indul ki. Ezek közül tekintünk át néhányat, a teljes lista ezen a linken található.
${#NÉV}: A NÉV változó értékének hosszát adja vissza karakterekben számolva.
${NÉV:index}: A NÉV változó értékének index. karakterétől kezdődő részsztringjét adja vissza. A karakterek indexelése 0-tól kezdődik! Ha index negatív (legyen -k), akkor az utolsó k darab karakterét adja eredményül. Ekkor elé - vagyis a ':' után - tenni kell egy szóközt a helyes működés érdekében!
${NÉV:index:hossz}: Hasonló a ${NÉV:index} művelethez, de legfeljebb hossz darab karakterből álló részsztringet ad vissza. index és hossz aritmetikai kifejezés is lehet.
${!NÉV}: Indirekció. A NÉV változó értékét változónévnek tekinti, s annak értékét adja eredményül.
${NÉV#minta}: Ha a minta illeszkedik a NÉV változó értékének elejére, akkor levágásra kerül a legrövidebb illeszkedő rész.
${NÉV##minta}: Ha a minta illeszkedik a NÉV változó értékének elejére, akkor levágásra kerül a leghosszabb illeszkedő rész.
${NÉV%minta}: Ha a minta illeszkedik a NÉV változó értékének végére, akkor levágásra kerül a legrövidebb illeszkedő rész.
${NÉV%%minta}: Ha a minta illeszkedik a NÉV változó értékének végére, akkor levágásra kerül a leghosszabb illeszkedő rész.
#!/bin/bash
val="sör.TXT.txt"
echo "Szöveg:" $val
echo "Szöveg hossza:" ${#val}
echo "2.-5. karakterek:" ${val:1:4}
echo "Utolsó 5 karakter:" ${val: -5}
echo " Első '.' előtti rész levágva:" ${val#*.}
echo "Utolsó '.' előtti rész levágva:" ${val##*.}
echo "Utolsó '.' utáni rész levágva:" ${val%.*}
echo " Első '.' utáni rész levágva:" ${val%%.*}
A kiírott szöveg:
Szöveg: sör.TXT.txt Szöveg hossza: 11 2.-5. karakterek: ör.T Utolsó 5 karakter: T.txt Első '.' előtti rész levágva: TXT.txt Utolsó '.' előtti rész levágva: txt Utolsó '.' utáni rész levágva: sör.TXT Első '.' utáni rész levágva: sör
Vegyük észre, hogy a ${NÉV%.*} művelet fájlnevek kiterjesztésének levágására akkor is használható, ha több '.' szerepel bennük.
Környezeti változók
(Kiegészítő anyag, nem lesz számonkérve!)
A futtatókörnyezet testreszabását teszik lehetővé, továbbá hasznos metaadatokat kérdezhetünk le velük a hatékonyabb programozás/automatizálás érdekében. Kevés kivétellel mindig nagybetűs nevük van. A BASH környezeti változók teljes listája megtalálható ezen az oldalon.
PWD: Az aktuális könyvtár (azaz munkakönyvtár) elérési útvonalát tárolja, amit a pwd paranccsal is lekérdezhetünk.
HOME: Az aktuális felhasználó home könyvtárának abszolút elérési útvonalát tárolja, amit a '~' hivatkozással is elérhetünk.
PATH: A keresési könyvtárak elérési útvonalát tárolja egymástól ':' karakterrel elválastva. Itt keresi a parancsokat a shell.
SHELL: A shell értelmező program abszolút elérési útvonalát tárolja, amely kezeli a terminálban kiadott parancsokat.
BASH: A BASH értelmező abszolút elérési útvonalát tárolja. Ha a SHELL változóban is ez szerepel, akkor a BASH az aktuális értelmező.
BASH_VERSION: A BASH értelmező aktuálisan telepített verzióját tárolja a bash --version parancshoz képest tömörebb módon.
IFS: A mezőelválasztó karaktereket tartalmazza egyetlen karakterláncként. Ezek alapértelmezetten a szóköz, vízszintes tabulátor és sortörés. Számít a sorrend!
SECONDS: A shell (terminál) indítása óta eltelt másodpercek számát adja vissza.
RANDOM: Egy 15-bites, előjel nélküli véletlen egész számot (0 – 32767) ad vissza.
SRANDOM: Egy 32-bites, előjel nélküli véletlen egész számot (0 – 4294967295) ad vissza. A BASH 5.1-es verziójától kezdődően érhető el.
Érték beolvasása
(Kiegészítő anyag, nem lesz számonkérve!)
read változó
A standard bemenetről tetszőleges változóba be tudunk olvasni egy sornyi szöveget.
#!/bin/bash
read VAL
echo $VAL
Beágyazott utasítás
Legtöbbször arra használjuk, hogy programkódon belül egy parancs vagy csővezeték kimenetét változónak adjuk értékül későbbi felhasználásra. Az alábbi két lehetőségünk van rá, a két szintaxis egyenértékű:
$(utasítás)
VAGY
`utasítás` # (AltGr+7)
Macskakörmök között megadva is végrehajtódnak, s behelyettesítésre kerül a kimenetük, azonban aposztrófok esetében már nem. Az alábbi utasítások eredményeképpen val1 és val2 értéke is "'Bela' nagybetűsítve: BELA" lesz.
#!/bin/bash
val1="'Bela' nagybetűsítve: $(echo 'Bela' | tr a-z A-Z)"
val2="'Bela' nagybetűsítve: `echo 'Bela' | tr a-z A-Z`"
Aritmetikai operátorok
Segítségükkel matematikai műveleteket hajthatunk végre numerikus (azaz számértéket tartalmazó) változókon és konstansokon. Részletesebb magyarázat az online dokumentációban olvasható.
Fontos! A BASH csak egész számokkal tud műveleteket végezni. Lebegőpontos számításokra egy különálló program ajánlott, méghozzá a basic calculator, azaz bc, lásd a POSIX szabványt és a GNU online dokumentációt. Ezt a parancsot jelen kurzuson nem tárgyaljuk.
Inkrementálás és dekrementálás operátorok: ++, --
Rendre 1-gyel növeli és csökkenti a változó értékét. Mindkét művelet prefix (pl. ++x) és postfix (pl. x--) alakban is használható.Elemi kétoperandusú operátorok: +, -, *, /, %, **
A '/' egész osztást jelent, az eredményből a törtrész mindig levágásra kerül.
Hatványozásra kizárólag a '**' használható, ugyanis '^' a bitenkénti kizáró vagy műveletre való.Értékadás operátorok: =, +=, -=, *=, /=, %=
Az eredményt az első operandusban tárolják el. Például az x+=y művelet x értékét y-nal növeli. Vegyük észre, hogy a hatványozás+felülírás - azaz '**=' - operátor NINCS definiálva.
Aritmetikai kifejezések
A BASH alapértelmezetten minden értéket szövegként kezel, emiatt külön jelölnünk kell a numerikus műveleteket. Az alábbi 3 lehetőség közül bármelyiket alkalmazhatjuk:
$((KIF)) vagy ((KIF))
A legrugalmasabb szintaxissal rendelkező módszer. A zárójelpáron belül nem érzékeny a szóközökre, és nem kötelező kitenni a '$' jelet a változónevek elé.
val=-6
szam=$((val * 7))
((val *= 2)) # Változó értékének frissítése esetén a nyitó zárójel előtt is elhagyható a '$'.
let KIF
Az értékadás művelet elé helyezett let kulcsszón kívül teljesen változatlan a kifejezés szerkezete.
val=5
let szam=$val*-3 # A negatív előjel a szorzás előtt értékelődik ki.
expr KIF
A kifejezés elemeit - operandusok, operátor - parancssori paraméterben átadva elvégzi a műveletet, és az eredményt a standard kimeneten adja vissza.
Részletesebben lásd: expr --help.
val=-3
szam=$(expr $val \* 13) # A '*' operátort escape-elni kell!
Parancssori paraméterek
$#: A parancssori paraméterek darabszáma.
$n: Az n. parancssori paraméter értéke. ($1 az első, $2 a második, …) Megjegyzés: Kizárólag ezek a speciális változónevek kezdődhetnek számjeggyel.
$0: Az aktuális program neve, vagyis a futtatáskor kiadott parancs első szava.
$*: Valamennyi parancssori paraméter egyben, egyetlen karakterláncként ("$1 $2 … $9 …"). Az egyes paraméterek az IFS változóban tárolt szöveg első karakterével vannak elválasztva, mely alapértelmezetten a szóköz.
$@: Hasonló a $*-hoz, viszont külön sztringekben tárolja a parancssori paramétereket. Ha idézőjelek között használjuk ("$@"), akkor a szóközöket tartalmazó paraméterek kezelésére is képes.
Segítségükkel legtöbbször inputot adunk át a program számára. Néhány gyakran használt, paraméterekkel kapcsolatos beépített változó:
Feltételes kifejezések, logikai operátorok
Shell programozási nyelvekben a numerikus és szöveges összehasonlításokon kívül a fájlrendszerben található könyvtárbejegyzésekről kérhetünk le információkat. Az operátorok teljes listája ezen a linken található.
Szám_1 -eq Szám_2 - - - Egyenlő # equal (A == operátor is használható.)
Szám_1 -ne Szám_2 - - - Nem egyenlő # not equal (A != operátor is használható.)
Szám_1 -lt Szám_2 - - - Kisebb # less than (A < operátor is használható.)
Szám_1 -le Szám_2 - - - Kisebb vagy egyenlő # less or equal (A <= operátor is használható.)
Szám_1 -gt Szám_2 - - - Nagyobb # greater than (A > operátor is használható.)
Szám_1 -ge Szám_2 - - - Nagyobb vagy egyenlő # greather or equal (A >= operátor is használható.)
Kif_1 && Kif_2 - - - - - Logikai ÉS # and (A -a kapcsoló is használható, leginkább a test parancsnál.)
Kif_1 || Kif_2 - - - - - Logikai VAGY # or (A -o kapcsoló is használható, leginkább a test parancsnál.)
!Kif - - - - - - - - - - Logikai tagadás
-z Sztring - - - - - - - 0 hosszúságú, azaz üres # zero
-n Sztring - - - - - - - nem 0 hosszúságú, azaz nem üres # non-zero (A -n kapcsoló elhagyható.)
Sztring != Sztring - - - nem egyenlők
Sztring = Sztring - - - egyenlők # A == operátor is használható.
# Ráadásul a mintaillesztés eszközeivel (*,?,[]) is működik.
Sztring =~ Regex - - - - A megadott sztring illeszkedését vizsgálja a reguláris kifejezésre.
-d útvonal - - - - - - - könyvtár # directory
-f útvonal - - - - - - - szabályos állomány # file
-L útvonal - - - - - - - szimbólikus link # Link (A -h kapcsoló is használható.)
-e útvonal - - - - - - - létezik # exist (Bármilyen típusú könyvtárbejegyzés lehet.)
útvonal_1 -nt útvonal_2 útvonal_1 újabb útvonal_2-nél # newer than
útvonal_1 -ot útvonal_2 útvonal_1 régebbi útvonal_2-nél # older than
útvonal_1 -ef útvonal_2 útvonal_1 és útvonal_2 azonos tartalmat jelöl # equal files
test parancs
(Kiegészítő anyag, nem lesz számonkérve!)
Feltételes kifejezések kiértékelésének egyik módja a test parancs vagy a vele ekvivalens (szokatlan elnevezésű) '[' parancs. Utóbbi esetben ']' a kötelező utolsó argumentum. A kiértékelés önmagában nem eredményez kiíratást, viszont a parancs visszatérési értéke (0 -> igaz; 1 -> hamis) eltárolásra kerül a $? környezeti változóban. Ez a parancs a következő operátorokat nem támogatja: <, <=, >, >=, =~. Megjegyzés: $? értéke bármely parancs végrehajtása után frissül, így mindig a legutóbb futtatott parancs "sikerességéről" szolgáltat információt.
# Kiértékeli a feltételt, és 0-ra (igaz) vagy 1-re (hamis) állítja a $? környezeti változót.
test feltétel
VAGY
[ feltétel ]
Összetett feltételt a -a és -o kapcsolókkal írhatunk, vagy a &&, || operátorokkal láncolhatjuk össze a kiértékelő parancsokat.
test feltétel1 (-a | -o) feltétel2 ...
test feltétel1 (&& | ||) test feltétel2 ...
VAGY
[ feltétel1 (-a | -o) feltétel2 ] ...
[ feltétel1 ] (&& | ||) [ feltétel2 ] ...
Általában a logikai feltételeket bizonyos utasítások végrehajtásának eldöntésére használjuk. A test (és '[') parancs esetében ez is a && és || (jelen esetben láncolási) operátor segítségével tehető meg. Ha valamelyik utasításblokk több parancsból áll, a csoportosítás érdekében { és } közé kell helyezni őket.
# A két utasításblokk bármelyike elhagyható.
test feltétel && igaz_utasításblokk || hamis_utasításblokk
VAGY
[ feltétel ] && igaz_utasításblokk || hamis_utasításblokk
Példák:
#!/bin/bash
# Ellenőrzi, hogy a megadott útvonalak ugyanoda mutatnak-e, vagyis az egyik linkel-e a másikra.
[ /bin -ef /usr/bin ] && echo "igen" || echo "nem" # Elvárt kimenet: igen
# a értéke 5-nél nagyobb-e, és b nemüres-e
a=3
b="szöveg"
test $a -gt 5 -a -n $b && echo "igen" || echo "nem" # Elvárt kimenet: nem
Valójában tetszőleges utasítás állhat a lánc elején, ugyanis minden parancsnak van visszatérési értéke (kilépési státusza). Sőt, akár átirányítást is alkalmazhatunk.
: '
Megpróbál új könyvtárat létrehozni a paraméterben kapott útvonalon.
Ha ez sikerül, tájékoztatja a felhasználót, és a cd paranccsal munkakönyvtárként kezdi használni.
Különben (például már létezik az útvonalon könyvtár) a megadott hibaüzenetet írja ki.
Mivel a standard hibakimenetet (2-es számú csatorna) irányítottuk át, az mkdir parancs hibaüzenetét nem fogjuk látni.
'
mkdir $1 2> /dev/null && { echo "$1 könyvtár sikeresen létrejött."; cd $1; } || echo "Nem sikerült. :("
Feladatok
1. Írj BASH szkriptet, amely egy sztringet és egy pozitív egész számot vár parancssori paraméterben! Írasd ki a sztring karaktereit a második paraméterben megadott sorszámtól kezdődően, de legfeljebb három darabot úgy, hogy az első karaktert az 1. pozíción feltételezzük! Példák:
- $ ./resz_sztring.sh Gyöngyös 3
öng - $ ./resz_sztring.sh Gyöngyös 7
ös - $ ./resz_sztring.sh OS 1
OS
2. Írj BASH szkriptet, amely egy fájl elérési útvonalát és két pozitív egész számot (legyenek rendre k és l) vár parancssori paraméterben! Írasd ki a megadott fájl k.–l. indexű sorait! Példák:
- $ ./tartomany.sh ekezetes_sorszamok.txt 3 5
harmadik
negyedik
ötödik - $ ./tartomany.sh ekezetes_sorszamok.txt 8 8
nyolcadik
3. Írj BASH szkriptet, amely tetszőlegesen sok egész számot vár parancssori paraméterben! Határozd meg a kapott számok számjegyeinek összesített darabszámát! Az esetleges +/- előjelet ne számold bele! Példák:
- $ ./szamjegy_darab.sh
0 - $ ./szamjegy_darab.sh +112 97
5 - $ ./szamjegy_darab.sh 223 9876 54
9 - $ ./szamjegy_darab.sh -666 +1001 911 -987654
16 - $ ./szamjegy_darab.sh 42 +899 0 -1 92929
12
4. Írj BASH szkriptet, amely két parancssori paramétert vár! Mindkét paraméter egy-egy szövegfájl legyen, melyek első sora egy-egy számot tartalmaz! Írasd ki ennek a két számnak az összegét!
Elvárt kimenet a szam_teszt1.txt és szam_teszt2.txt fájlokra: 150
B2
Zárójel típusok feltételes kifejezések kiértékelésére
[ ] -> szögletes zárójel
Támogatja a kapcsolókat (-eq, -lt, -z, -e, …) és a sztringek összehasonlítását (=, !=).
Nem támogatja a <, <=, >, >= relációs operátorokat és a regexre illesztést (=~).
(( )) -> dupla kerek zárójel
Támogatja a ==, !=, <=, >=, <, > relációs és az aritmetikai (+, -, …) operátorokat.
Nem támogatja a kapcsolókat, sztringek összehasonlítását és a regexre illesztést.
[[ ]] -> dupla szögletes zárójel
Támogatja a kapcsolókat (kivéve -a és -o) és a sztringek összehasonlítását.
Sztringek egyezésén (=, !=) kívül a lexikografikus összehasonlítást is lehetővé teszi a < és > operátorokkal.
Támogatja a =~ operátort.
Nem támogatja a <= és >= operátorokat.
Sok más programozási nyelvhez hasonlóan a ( ) kerek zárójelpár leginkább a műveleti sorrend felülbírálása használható, míg a { } kapcsos zárójelpár programblokkokat (pl. függvények) határoz meg. Feltételes kifejezések kiértékelésére az alábbi három zárójel típus használható.
Bár a '[' nyitó zárójel önálló parancsként is értelmezett, ugyanazzal a szintaxissal vezérlési szerkezetekben is használható.
Feltételes kifejezésekben is az aritmetikai (numerikus) műveleteket teszi lehetővé. Nem érzékeny a szóközökre, és nem kötelező kitenni a '$' jelet a változónevek elé.
A legszélesebb funkcionalitással rendelkező típus, mivel a legtöbb operátort támogatja. Egy remek összehasonlítás az egyszeres zárójelpárral ezen a linken olvasható.
Vezérlési szerkezetek (1. rész)
if utasítás
A szelekciós vezérlést (elágazást) valósítja meg számos más programozási nyelvhez hasonlóan. A behúzás/indentálás tetszőleges mértékű lehet.
if feltétel; then
utasításblokk
elif feltétel; then # Elhagyható rész. Több elif ág is lehet egymás után.
utasításblokk
else # Szintén elhagyható rész.
utasításblokk
fi
# Egyetlen sorba is írható, ekkor viszont minden utasítás után pontosvesszőt kell tenni!
if feltétel; then utasításblokk; elif feltétel; then utasításblokk; else utasításblokk; fi
#!/bin/bash
if [[ $1 -lt 9 ]]; then
echo "A paraméter 9-nél kisebb."
fi
#!/bin/bash
v1="Bela"
v2="Jeno"
if [[ $v1 != $v2 ]]; then
echo "A két sztring nem egyezik meg." # Ez fog végrehajtódni.
else
echo "A két sztring megegyezik."
fi
#!/bin/bash
if [[ $# -eq 1 && $1 -ge 1 && $1 -le 10 ]]; then
echo "A parancssori paraméter értéke 1 és 10 között van."
fi
# Ugyanez másképpen
if (($# == 1 && $1 >= 1 && $1 <= 10)); then
echo "A parancssori paraméter értéke 1 és 10 között van."
fi
#!/bin/bash
if [[ ! -e $1 ]]; then
echo "A(z) $1 útvonalon nem található semmiféle könyvtárbejegyzés."
fi
#!/bin/bash
v=""
if [[ -n $v ]]; then # A -n kapcsoló elhagyható
echo "A változó nem üres."
fi
#!/bin/bash
n1=6
n2=42
if (( $n1 < $n2 )); then
echo "6 kisebb, mint 42." # Ez fog végrehajtódni.
else
echo "6 NEM kisebb, mint 42."
fi
# Ügyeljünk arra, hogy a < és > operátor lexikografikus összehasonlítást végez szögletes dupla zárójelpár között!
if [[ $n1 < $n2 ]]; then
echo "6 lexikografikusan kisebb, mint 42."
else
echo "6 lexikografikusan NEM kisebb, mint 42." # Ez fog végrehajtódni.
fi
for - lista alapú
# A változó rendre felveszi a lista elemeinek értékét, és minden értékkel végrehajtódik az utasítás blokk.
for változó in lista; do
utasításblokk
done
# Egyetlen sorba írva:
for változó in lista; do utasításblokk; done
VAGY
# Az n-től m-ig tartó (egész) számtartomány elemein megy végig. n és m is csak konstans egész lehet!
for változó in {n..m}; do
utasításblokk
done
# Egyetlen sorba írva:
for változó in {n..m}; do utasításblokk; done
Előbbi esetben a lista lehet:
- szavak szóközökkel elválasztva,
- mintaillesztéssel megadott könyvtárbejegyzések (pl. *),
- változók szóközökkel elválasztva (pl. $a $b $c), vagy
- $(…) vagy `…` szerkezettel megadott beágyazott utasítás kimenete.
# Kiírja a hét napjait.
for nap in hétfő kedd szerda csütörtök péntek szombat vasárnap; do
echo $nap
done
# Kiírja a kapott parancssori paramétereket, méghozzá felsorolási sorrendben.
for param in $*; do
echo $param
done
# Kilistázza az aktuális könyvtárban található összes txt kiterjesztésű állományt.
for fajl in $(ls *.txt); do
echo $fajl
done
for - index alapú
A C nyelvből (cshell-ből) átvett számlálós for ciklus. A fejléc három kifejezésből áll, melyek bármelyike elhagyható.
for (( KIF1;KIF2;KIF3 )); do
utasításblokk
done
# Egyetlen sorba írva:
for (( KIF1;KIF2;KIF3 )); do utasításblokk; done
A kifejezések szerepe:
- KIF1: Az első iteráció (ciklusmag egyszeres lefutása) előtt hajtódik végre. Tipikusan a ciklusváltozó inicializálására használjuk.
- KIF2: A folytatási feltétel, mely mindig logikai kifejezésként értékelődik ki. Logikai operátorokat (&&, ||) is használhatunk. Ha üresen hagyjuk, azonosan igaznak tekinti, tehát mindig egy új iterációt kezd. Ebben az esetben a ciklusmagban kell egy kilépési feltételt megadni a végtelen ciklus elkerülése érdekében.
- KIF3: Közvetlenül a ciklusmagot követően fut le minden egyes iteráció végén. Tipikusan a ciklusváltozó frissítésére (pl. inkrementálás) használjuk.
# Kiírja 1-től az első paraméter értékéig az egész számokat.
for (( i=1; i<=$1; ++i )); do
echo $i
done
# Kiírja - szintén a felsorolás sorrendjében - a parancssori paramétereket.
for (( i=1; i<=$#; ++i )); do
echo ${!i} # Az i. paraméter értékének behelyettesítése indirekcióval történik.
done
Feladatok
1. Írj BASH szkriptet, amely for ciklussal megszámolja a parancssori paraméterben kapott egész számok számjegyeit! Az esetleges +/- előjelet ne számold bele! Példák:
- $ ./szamjegy_darab.sh
0 - $ ./szamjegy_darab.sh +112 97
5 - $ ./szamjegy_darab.sh 223 9876 54
9 - $ ./szamjegy_darab.sh -666 +1001 911 -987654
16 - $ ./szamjegy_darab.sh 42 +899 0 -1 92929
12
2. Írj BASH szkriptet, amely egy könyvtár útvonalát várja parancssori paraméterben! Járd be a könyvtár tartalmát for ciklussal, és írasd ki az összes nem rejtett fájl nevét! Az esetleges alkönyvtárakat ne járd be rekurzívan! Elvárt kimenet a konyvtar.zip fájlban található könyvtárra:
- $ ./fajlok.sh konyvtar
GAWK.xml
NotepadPlusPlus_PATH.pdf
input-output.png
3. Írj BASH szkriptet, amely megállapítja, hogy a paraméterben kapott egész szám prímszám-e! Egy pozitív egészet prímnek nevezünk, ha pontosan két pozitív osztója van: 1 és önmaga. Példák:
- $ ./prim.sh -11
nem - $ ./prim.sh 1
nem - $ ./prim.sh 7
igen - $ ./prim.sh 27
nem - $ ./prim.sh 89
igen - $ ./prim.sh 211
igen - $ ./prim.sh 929
igen - $ ./prim.sh 1001
nem
B3
Vezérlési szerkezetek (2. rész)
while
Az első iteráció előtt kiértékeli a feltételt, emiatt előfordulhat, hogy egyszer sem hajtódik végre a ciklusmag. BASH-ben nincs hátultesztelős ciklus.
while feltétel; do
utasításblokk
done
# Egyetlen sorba írva:
while feltétel; do utasításblokk; done
# Három másodpercenként kiírja a 'Futok...' szöveget.
while true; do
echo "Futok..."
sleep 3 # A sleep parancs felfüggeszti a program futását a paraméteben kapott időtartamra (másodpercben).
done
until
(Kiegészítő anyag, nem lesz számonkérve!)
Az until szerkezet addig ismétli az utasításblokkot, amíg a feltétel visszatérési értéke hamis. A while szerkezethez képest tehát a feltételes kifejezés értelmét az ellentettjére változtatja.
until feltétel; do
utasításblokk
done
# Egyetlen sorba írva:
until feltétel; do utasításblokk; done
case
(Kiegészítő anyag, nem lesz számonkérve!)
Az esetkiválasztásos vezérlést valósítja meg. A mintákat a felsorolás sorrendjében próbálja meg illeszteni a megadott szövegre, és illeszkedés esetén végrehajtja a hozzá tartozó utasításblokkot. Az áttekinthetőség érdekében nem érdemes egyetlen sorba belepaszírozni a teljes parancsot.
case szó in
minta_1a | minta_1b ) # A minta tetszőleges szöveg lehet. Sőt, a mintaillesztés eszközei (*, ?, [halmaz]) is alkalmazhatóak.
utasításblokk_1 ;;
minta_2 )
utasításblokk_2 ;;
.
.
.
* ) # default ág, akár el is hagyható
utasításblokk_n
esac # fun fact: ez a "case" visszafelé
Az utasításblokkok után helyezett határolójel típusától függően az alábbi viselkedések lehetségesek:
;; - Csak az első illeszkedő mintához tartozó blokkot hajtja végre.
;& - Az első illeszkedő mintától indulva az összes blokkot végrehajtja, a további mintákra illeszkedéstől függetlenül.
;;& - Az összes illeszkedő mintához tartozó blokkot végrehajtja.
# A parancssori paraméter értéke alapján kommenteli a hét napját az alábbi opciók egyikével.
case $1 in
1 )
echo "Hinnye, de nagyon hétfő." ;;
2 )
echo "Szinte hétfő." ;;
3 | 4 )
echo "Na közeledünk." ;;
5 | 6 )
echo "Azért ez már valami." ;;
7 )
echo "Jajj, anyám.." ;;
* ) echo "rossz input"
esac
Ugró utasítások
break
continue
Azonnal megszakítja a ciklus futását. A vezérlés közvetlenül a ciklust követő utasítással folytatódik. Beágyazott ciklusok esetén csak a legbelsőből lép ki.
Csak az aktuális iteráció futását szakítja meg a cikluson belül. A következő iteráció megkezdése előtt frissíti a ciklusváltozót.
#!/bin/bash
: '
Az alábbi szkript egy végtelen ciklust tartalmaz, mely 1-től kezdve összeadja a számokat.
Mielőtt hozzáadnánk az összeghez az aktuális számot, megnézzük, hogy az összeg meghaladta-e a 100-as értéket.
Amennyiben igen, kilépünk a ciklusból.
Ha az adott szám osztható 5-tel, akkor az összeg növelése nélkül ugrunk a következő iterációra.
'
osszeg=0
val=0
while true; do
let val+=1
echo "val: $val"
if (( $osszeg >= 100 )); then # Lehetne [[ $osszeg -ge 100 ]] is.
break
fi
if (( $val%5 == 0 )); then # Lehetne [[ $val%5 -eq 0 ]] is.
continue
fi
((osszeg += val))
echo osszeg: $osszeg
done
echo $val
echo $osszeg
exit [kilépési kód]
Ahol kiadjuk ezt a parancsot, ott terminál a program. Megadhatunk neki kilépési kódot, melynek 0 és 255 közötti egésznek kell lennie! Argumentum nélkül a legutóbb végrehajtott utasítás kilépési státuszával - vagyis a $? értékével - lép ki. A 0 jelzi, ha minden rendben volt.
#!/bin/bash
: '
Megpróbálunk létrehozni egy "mappa" nevű könyvtárat.
A standard hibakimenetet (2) átirányítjuk a "nyelőre", így elrejthetjük az esetleges hibaüzenetet.
Ha sikerül, akkor $? értéke 0 lesz. Ellenkező esetben az else ág fut le.
'
mkdir mappa 2> /dev/null
if (( $? == 0 )); then
echo "Sikeres volt az előző művelet."
else
echo "Sikertelen volt az előző művelet." >&2
exit 1
fi
echo "Ha sikertelen volt, akkor ide már nem jut el a program."
Program eleji validáció utolsó utasítása is lehet az exit parancs, amennyiben egy adott "beugró" feltétel nem teljesül.
#!/bin/bash
if (( $# == 0 )); then
echo "Nem adtál meg paramétert!" >&2
exit 8
fi
Feladatok
1. Írj BASH szkriptet, amely 3 parancssori argumentumot vár: egy egész értéket, egy aritmetikai operátort (+, -, *, / vagy %) és még egy egész értéket! A kimenet az adott két egészen végrehajtott művelet eredménye legyen! Amennyiben nem 3 paramétert kap a program, írasd ki a standard hibakimenetre a "Pontosan 3 paraméter kell!" szöveget! Ha pedig a 2. argumentum nem az öt műveleti jel egyike, az "Ismeretlen művelet!" szöveget írasd ki a standard hibakimenetre! Példák:
- $ ./szamologep.sh 81
Pontosan 3 paraméter kell! - $ ./szamologep.sh 5 = 9
Ismeretlen művelet! - $ ./szamologep.sh 13 + 29
42 - $ ./szamologep.sh 7 - 13
-6 - $ ./szamologep.sh -3 \* 11 # A * karaktert escape-elni kell, ami a '*' alakban is megoldható.
-33 - $ ./szamologep.sh 50 / 9
5 - $ ./szamologep.sh 234 % 7
3
2. Írj BASH szkriptet, amely kiírja a paraméterként kapott (akár nem létező) fájlnevek kiterjesztését, vagyis az utolsó '.' karakter utáni részt! Minden kiterjesztés nélküli paraméterre kizárólag egy-egy üres sort írass ki! A szkriptnek szóközöket tartalmazó útvonalakra is helyesen kell működnie! Példák:
- $ ./kiterjesztes.sh "BCC simple.lut" helloworld/main.cpp
lut
cpp - $ ./kiterjesztes.sh "nincs kiterjesztés" ../ZH/megoldások.sh /bin/bash ./.titkos/sör.xlsx
sh
xlsx - $ ./kiterjesztes.sh "/home/teszt.elek/.filmek/Brian élete.mp4" "rage games/cat mario" "./confidential documents/beginners manual.pdf"
mp4
pdf
3.* Írj BASH szkriptet, amely a factor parancs használata nélkül állítja elő a paraméterben kapott 1-nél nagyobb egész szám prímtényezős felbontását, méghozzá soronként egy-egy tényezővel, növekvő sorrendben! Ha a kapott szám 2-nél kisebb, írasd ki a "Fatal error!" szöveget a standard hibakimenetre, és lépj ki 12-es hibakóddal! Példák:
- $ ./primfelbontas.sh -7
Fatal error! - $ ./primfelbontas.sh 12
2
2
3 - $ ./primfelbontas.sh 89
89 - $ ./primfelbontas.sh 513
3
3
3
19 - $ ./primfelbontas.sh 1002
2
3
167
További gyakorlófeladatok
Figyelem! Az alábbi feladatsorok a 2020-as anyagrészhez vannak igazítva, akkor készült a videósorozat is. Az aktuális anyagot nem fedik le teljesen!
Cservenák Bencétől: feladatlap, tesztfájlok és egy lehetséges megoldás
Madarász Mátétól: feladatlap, tesztfájlok és egy lehetséges megoldás
A1
Reguláris kifejezések
Regular expression / regex(p). Abban az esetben, ha összetettebb lekérdezéseket szeretnénk, amelyben a szöveg valamilyen mintára illeszkedése alapján szeretnénk szűréseket végrehajtani, akkor a reguláris kifejezések használata hasznos lehet. Gyakori alkalmazása például hasonló elemek vagy hasonló kategóriába tartozó szövegek (weboldalak címei, email címek, dátumok, …) keresése. Az alap és kiterjesztett regexek általános felépítési/működési elvárásait a POSIX szabvány foglalja össze.
Egy kis emlékeztető néhány kiegészítővel: egrep (az L2 anyagrészből)
- egrep [kapcsolók] <regex> <fájl>
Kiírja egy fájl azon sorait, amelyek illeszkednek a (kiterjesztett) reguláris kifejezésre.
Kapcsolók:
-c: Az illeszkedő sorok tartalma helyett csak azok darabszáma jelenik meg.
-n: Az illeszkedő sorok sorazonosítóját is kiírja.
-v: Az illeszkedés tiltása (negálás).
-e <minta>: Több minta megadásakor használandó. Ekkor legalább az egyik mintára való illeszkedést követeljük meg.
-r, -R: Könyvtárban szereplő fájlok feldolgozása rekurzívan.
Elemi kifejezések:
KARAKTER - Bármely közönséges karakter saját maga egy példányára illeszkedik.
\KARAKTER - A \ után írt speciális jelentésű karaktert közönségesként kezeli.
() - Az üres szóra illeszkedik.
(KIF) - A zárójelen belül megadott szövegre fog illeszkedni. A műveleti sorrend felülbírálása miatt is fontos lehet!
[HALMAZ] - A halmaz bármely karakterének egy példányára illeszkedik. A halmazt a karakterek egymás mellé írásával adhatjuk meg.
A POSIX szabvány szerint a halmazon belül (kevés kivétellel, pl. \) a speciális karakterek is közönségesnek számítanak. Halmazon belül karakter osztályokat is megadhatunk, lásd alább.[TÓL-IG] - Mint előbb, de itt egy tartományt adunk meg. Kombinálható a halmaz szerkezettel. Sőt, akár több tartományt is megadhatunk
[^HALMAZ] - A halmazban nem szereplő bármely karakter egy példányára illeszkedik (a sortörést kivéve).
. - Bármilyen karakter egy példányára illeszkedik (a sortörést kivéve).
^ - A sor elejére illeszkedik.
$ - A sor végére illeszkedik.
Karakter osztályok
(Kiegészítő anyag, nem lesz számonkérve!)
Programozási nyelvtől függően többféle előre definiált karakter osztályra szűrhetünk.
Szkriptnyelvekben (pl. Python, Javascript) népszerűek a \<betű> alakú, ún. escape karakter osztályok.
Például a \d jelölés a számjegyeket foglalja magába.
A POSIX szabvány nem támogatja az escape karakter osztályokat, helyettük [:NÉV:] alakban definiál összesen 12 osztályt. Ezek közül néhány:
[:upper:] - Nagybetűkre illeszkedik, az LC_CTYPE beállításától függően.
[:lower:] - Kisbetűkre illeszkedik, az LC_CTYPE beállításától függően.
[:alpha:] - Betűkre illeszkedik, az LC_CTYPE beállításától függően.
[:digit:] - Számjegyekre illeszkedik, mint a 0-9 tartomány.
[:alnum:] - Betűkre és számjegyekre illeszkedik, az LC_CTYPE beállításától függően.
[:space:] - Whitespace karakterekre (pl. szóköz, \t, \n, \r) illeszkedik.
Fontos! Ezek a karakter osztályok csak halmazban alkalmazhatók. Helyes használatukra példák a [[:alnum:]] vagy a [[:alpha:]_]. Utóbbi a betűkön kívül az '_' karakterre is illeszkedik, mivel hozzáadtuk a halmazhoz.
Összetett kifejezések:
KIF1KIF2 - összefűzés, konkatenáció
KIF1|KIF2|… - Logikai MEGENGEDŐ VAGY, alternáció. Olyan szövegre illeszkedik, amely legalább az egyik kifejezésre illeszkedik.
A precedencia szabály miatt (lásd alább) célszerű zárójelbe helyezni, vagyis (KIF1|KIF2| . . .) alakban használni.KIF* - KIF akárhány egymást követő példányára illeszkedik (0 is)
KIF+ - KIF legalább 1 egymást követő példányára illeszkedik
KIF? - KIF 0 vagy 1 példányára illeszkedik (azaz KIF opcionális)
KIF{I} - KIF pontosan I egymást követő példányára illeszkedik
KIF{I,} - KIF legalább I egymást követő példányára illeszkedik
KIF{,J} - KIF legfeljebb J egymást követő példányára illeszkedik (nincs alsó korlát)
KIF{I,J} - KIF legalább I, de legfeljebb J egymást követő példányára illeszkedik (I <= J)
Ismételt illesztés, ismétlésszám megadása, iteráció:
Vegyük észre, hogy a * és a ? karakternek más a szerepe, mint a hagyományos mintaillesztés során.
Műveleti erősség csökkenő sorrendben: iteráció, konkatenáció, alternáció.
Ajánlások gyakorlásra:
Az egrep parancs --color kapcsolójának használata, mely kiszínezi az illeszkedő szövegrészeket.
A GAWK online regex dokumentációjának tanulmányozása.
Regexek gyakorlására szolgáló weboldalak látogatása, például:
Példák:
'alma' - az "alma" sztring a soron belül bárhol előfordulhat
'^alma' - az "alma" sztringnek a sor elején kell előfordulnia
'^alma$' - a teljes sor csupán az "alma" sztringből állhat
'(alma){2}' - az "alma" sztringnek kétszer kell szerepelnie közvetlenül egymás után.
karaigabor@karaigabor:~/Dokumentumok$ cat file.txt ebben a sorban van alma alma almafa zoldalmaalmapalinka vmi az alma is alma karaigabor@karaigabor:~/Dokumentumok$ egrep --color 'alma' file.txt ebben a sorban van alma alma almafa zoldalmaalmapalinka vmi az alma is alma karaigabor@karaigabor:~/Dokumentumok$ egrep --color '^alma' file.txt alma almafa karaigabor@karaigabor:~/Dokumentumok$ egrep --color '^alma$' file.txt alma karaigabor@karaigabor:~/Dokumentumok$ egrep --color '(alma){2}' file.txt zoldalmaalmapalinka
Feladatok
1. Dátum ellenőrzése reguláris kifejezéssel. (közelítő megoldás)
Példafájl: date.txt
Elvárt kimenet a date.txt alapján:
2018.04.12. 2018/04/12 1999-01-01 1456.06.07.
Egy lehetséges megoldás:
egrep --color '^[0-9]{4}[./-](0[1-9]|1[012])[./-](0[1-9]|[12][0-9]|3[01])[./-]?$' date.txt
Magyarázat:
Sor elején kezdődjön | 4 darab szám | | Az alábbi karakterek egyike: '.' '/' '-' | | | 01–09 10–12 | | | | | 01–09 10–29 30–31 vagy van, vagy nincs elválasztójel a végén | | | | | | | | | a sor végéig tartson az illesztés | | | | | | | | | | _ ______ ___ ____ ____ ____ _______ ___ _ _ | || || | | | | | | | | | | | | || | egrep --color ' ^ [0-9]{4}[./-] (0[1-9]|1[012])[./-] (0[1-9]|[12][0-9]|3[01])[./-] ? $' date.txt
Megjegyzés: A szóköz közönséges karakternek számít regexekben, emiatt futtatáskor nem szabad benne hagyni a csupán tagolásra szolgáló karaktereket!
2. Email cím ellenőrzése reguláris kifejezéssel. (közelítő megoldás)
Példafájl: email.txt
Az elvárt kimenet az email.txt alapján:
jmcnamara@verizon.net.net emmanuel@yahoo.com arandal@mac.com netsfr@outlook.com moinefou@sbcglobal.net jmorris@mac.com kewley@yahoo.info multiplx@yahoo.com paina@outlook.com user@inf.u-szeged.hu
Egy lehetséges megoldás:
egrep --color '^[0-9a-z.-]+@([0-9a-z-]+\.)+[a-z]{2,4}$' email.txt
Magyarázat:
Lehet bármilyen szám, kisbetű, pont vagy kötőjel. | Ezen karakterekből egymás után tetszőlegesen sok, de legalább egy darab szerepel. | | Hasonló, mint az előző, viszont a pont csak a végén lehet, és ebből a | | módosított mintából kell legalább egynek lennie. | | | A végén csak kisbetűk lehetnek, | | | | és azokból is legalább egy darab. | | | | | ________ _ ____________ ___ _ | || | | | | || | egrep --color '^[0-9a-z.-] + @ ([0-9a-z-]+\.)+[a-z] + $' email.txt
AWK
Szövegfeldolgozó nyelv. Az AWK név a megalkotói - Alfred Aho, Peter Weinberger és Brian Kernighan - vezetéknevének kezdőbetűiből keletkezett. Szintaktikája nagyon hasonlít a C nyelvhez, ugyanis Kernighan a C nyelv létrehozásában is közreműködött. Több implementációja is létezik, mindegyik a POSIX szabványra épít. Jelen kurzuson a GNU AWK (gawk) változatot használjuk, mely a legtöbb Linux disztribúcióban gyárilag szerepel. Ráadásul a Cygwin emulátor is tartalmazza ezt a variánst. A legtöbb GNU csomaghoz hasonlóan jól dokumentált.
Az AWK szkriptek kiterjesztése awk.
A szkript első sora (She-Bang / Hash-Bang):
#!/bin/gawk -f
A '!' után opcionálisan szóköz/tabulátor szerepelhet. A futtatás hasonló a bash-nél tanult módhoz:
./fájlnév.awk [kapcsolók] [fájl1 fájl2 …]
A fenti utasítás az alábbival ekvivalens:
gawk -f fájlnév.awk [kapcsolók] [fájl1 fájl2 …]
Bár a félév során az AWK szkripteket mindig külön fájlokba írjuk - mivel a ZH-n is erre lesz szükség -, fontos megemlíteni, hogy terminálban is közvetlenül alkalmazhatók. A beágyazott AWK szkriptet aposztrófok közé kell tenni, mert az idézőjel (macskaköröm) az AWK sztringek határolójele.
Az ls -l parancs kimenetét dolgozza fel.
ls -l | gawk [kapcsolók] '<szkript>'
A felsorolt szöveges fájlok tartalmát dolgozza fel.
gawk [kapcsolók] '<szkript>' [fájl1 fájl2 …]
Felépítés
Minden AWK forrásprogram szabályok / blokkok sorozata. Minden szabály tartalmazhat egy mintát és egy hozzátartozó tevékenységet avagy akciót. Az akciót különféle utasításokból állíthatjuk össze.
A szabályok alakja: MINTA { AKCIÓ }, ahol a MINTA valamilyen logikai feltétel, az AKCIÓ pedig legtöbbször utasítások sorozata. Fontos! Az AKCIÓ kezdetét jelző '{' karakter mindig a MINTA sorának végére kerüljön!
A szabályokat egymástól sortöréssel vagy pontosvesszővel lehet elválasztani.
A feldolgozás során a bemenet tartalmát rekordokra bontja, ezek alapesetben a bemenet sorai lesznek. A rekordokat szintén tovább-bontja mezőkre, amiket alapesetben az adott sor szavai képviselnek.
Példaként legyen egy szöveges fájl tartalma az alábbi:
Ezt a szöveges fájlt szeretném feldolgozni. A gyakorlaton való bemutatás érdekében.
Ekkor mind a két sor 1-1 rekordnak minősül. Egy rekord teljes tartalmára $0-val lehet hivatkozni. A szavak pedig 1-1 mezőnek felelnek meg, melyekre a $1,$2,…,$n beépített változókkal hivatkozhatunk. Figyelem! Ezeknek a szimbólumoknak semmi közük a program parancssori paramétereihez!
$1 $2 $3 $4 $5 $6 $0 -> Ezt a szöveges fájlt szeretném feldolgozni. $0 -> A gyakorlaton való bemutatás érdekében.
A bemenet feldolgozása tehát rekordonként történik. Minden rekordot megpróbál illeszteni sorban az összes szabály mintájára, az első szabálytól kezdve. Ha a rekord illeszkedett egy szabály mintájára, akkor végrehajtódik a hozzá tartozó akció. Végül az összes szabály ellenőrzése után rátér a következő rekord feldolgozására.
Egy awk program sematikus felépítése:
#!/bin/gawk -f
BEGIN {
utasítások
}
# Csak gawk-ban létezik!
BEGINFILE {
utasítások
}
[MINTA] {
főprogram-blokk_1
}
.
.
.
[MINTA] {
főprogram-blokk_n
}
# Csak gawk-ban létezik!
ENDFILE {
utasítások
}
END {
utasítások
}
BEGIN - Csak a bemenet feldolgozása előtt teljesül. A BEGIN mintához tartozó akció pontosan egyszer hajtódik végre, mégpedig a legelső bemeneti rekord feldolgozása előtt. Ez akkor is így történik, ha több bemeneti állományt adtunk meg.
BEGINFILE (gawk specifikus, nem lesz számonkérve!) - A soron következő bemeneti állomány feldolgozása előtt teljesül. A BEGINFILE mintához tartozó akció a bemeneti fájlok darabszámával megegyező alkalommal hajtódik végre.
A „főprogram blokkok” előtti feltétel (minta) teljesülését minden rekordra önműködően ellenőrzi a felsorolt sorrendben, s a bennük található utasításokat végrehajtja. Tehát a program eleve tartalmaz egy rejtett (implicit) ciklust. Ha nem adunk meg mintát, akkor azonosan igaznak tekinti, vagyis minden rekordra végrehajtja az adott blokkot.
ENDFILE (gawk specifikus, nem lesz számonkérve!) - A soron következő bemeneti állomány feldolgozása után teljesül. A BEGINFILE mintához hasonlóan, az ENDFILE mintához tartozó akció is a bemeneti fájlok darabszámával megegyező alkalommal hajtódik végre.
END - Csak a bemenet feldolgozása után teljesül. A BEGIN mintához hasonlóan, az END mintához tartozó akció is pontosan egyszer, az utolsó bemeneti rekord feldolgozása után hajtódik végre. Ezt az awk program befejeződése követi.
Vegyük észre, hogy AWK-ban - ahogy BASH-ben is - '#' karakterrel kezdődnek az egysoros kommentek. Azonban AWK-ban többsoros megjegyzés közvetlenül nem illeszthető be, csak egysoros kommentek egymás után írásával tehető ez meg.
Minták (feltételek)
Relációs kifejezések: <, <=, >, >=, ==, !=
Elsősorban számok összehasonlítására szolgálnak, de sztringekre is működnek.Logikai operátorok:
- !MINTA - tagadás, negáció
- MINTA1 && MINTA2 - és művelet, mindkét mintára illeszkedik
- MINTA1 || MINTA2 - megengedő vagy művelet, legalább az egyik mintára illeszkedik.
(MINTA) - Csoportosítás, műveleti sorrend felülbírálása.
/REGKIF/ - Igaz, ha az egész rekord illeszkedik a reguláris kifejezésre. Ekvivalens a $0 ~ /REGKIF/ alakkal.
KIF ~ /REGKIF/ - Igaz, ha a KIF kifejezés mint szöveg illeszkedik a reguláris kifejezésre.
KIF !~ /REGKIF/ - Igaz, ha a kifejezés nem illeszkedik a REGKIF-re.
Kiíratás
print [LISTA] - Önmagában az aktuális rekordot ($0) írja ki. Egyébként a vesszővel tagolt argumentumainak értékét írja ki, alapértelmezetten szóközzel elválasztva. Végül - alapértelmezett módon - egy sortörés karaktert is beilleszt. Ha nem teszünk vesszőt az argumentumok közé, egyszerűen összefűzi őket.
printf FORMÁTUM[, LISTA] - Formázott kiíratás a C nyelvbeli printf függvényhez hasonló módon. Az utasítás argumentumai zárójelben is felsorolhatók, azaz printf(FORMÁTUM[, LISTA]) alakban, mintha függvény lenne. A print paranccsal ellentétben nem dob automatikusan új sort, és kötelező vesszőt tenni a LISTA elemek közé.
Vegyük észre, hogy a következő utasításokkal dobhatunk pontosan egy új sort: print ""; printf "\n" vagy printf("\n").
1. példa:
#!/bin/gawk -f
BEGIN { print "BEGIN blokk...\n" }
BEGINFILE { print "BEGINFILE blokk..." }
{ print "Főprogram blokk..." }
ENDFILE { print "ENDFILE blokk...\n" }
END { print "END blokk..." }
Kimenet két darab egysoros bemeneti fájl esetén:
BEGIN blokk... BEGINFILE blokk... Főprogram blokk... ENDFILE blokk... BEGINFILE blokk... Főprogram blokk... ENDFILE blokk... END blokk...
2. példa:
#!/bin/gawk -f
BEGIN {
printf("Hello World!\n\n")
}
{
# A bemeneti fájlból csak az első oszlopot írja ki.
print $1
}
Kimenet a fenti kétsoros szövegre:
Hello World! Ezt A
Az utasítások után csak akkor kell ';', ha ugyanabba a sorba még legalább egy utasítást írunk.
Feladatok
1. Írj AWK szkriptet, amely egy, az ls -l parancs egy lehetséges kimenetét tartalmazó fájlt kap bemenetként! Listázd ki a szabályos állományok nevét! Feltételezzük, hogy minden fájlnév egyetlen szóból áll.
Elvárt kimenet (részlet) az ls-l.txt fájlra:
1.txt
2.txt
3.txt
akarmi
akarmi2
date.txt
…
2.* Írj AWK szkriptet, amely egy, soronként egy-egy (egyszavas) jelszót tartalmazó fájlt kap bemenetként! Listázd ki azokat a 8–16 karakter hosszúságú jelszavakat, melyek tartalmaznak számjegyet, ékezet nélküli kis- és nagybetűt, valamint a következő speciális karakterek legalább egyikét: (? ! _ - + %)!
A jelszó csak a felsorolt karakter osztályokból állhat!
Elvárt kimenet a password.txt fájlra:
SZuperT1tk?s
pa33worD%
Gumi-macik1991
0TipszMiksz+
OS_Free_Cred!t42
3. Írj AWK szkriptet, amely kiírja a bemeneti fájl 2. és 1. oszlopát!
Elvárt kimenet (részlet) a szamok1.txt fájlra:
1234 -24
1001 11
0 5
He? 16
…
4. Írj AWK szkriptet, amely a bemeneti fájlok utolsó sorát írja ki!
Elvárt kimenet az ekezetes_sorszamok.txt és ekezetes_szamok.csv fájlokra:
tizedik
tíz;2
További gyakorlófeladatok
Cservenák Bencétől: feladatlap, tesztfájl és egy lehetséges megoldás
Madarász Mátétól: feladatlap, tesztfájlok és egy lehetséges megoldás
A2
Konstansok
Számok:
- egész számok, például: 1, -23, 184, 1354
- valós számok, például: 0.5, 1.23, -125.511
Sztringek:
- "szöveg"
- "" (üres sztring)
Standard regexek:
Kizárólag idézőjelek (macskakörmök) között adhatóak meg, az aposztróf a beágyazott awk szkript határolójele.
Speciális karaktereket escape-eléssel, vagyis a '\' karakter használatával illeszthetünk be.
/REGEX/ alakúak. Közvetlen mintaillesztéshez használhatóak '~' és '!~' operátorokkal, valamint néhány beépített függvénynek paraméterként adhatóak át. Változónak viszont nem tudjuk őket értékül adni, erre gawk-ban a @/REGEX/ alakú erősen típusos regexek alkalmasak.
Változók
Típusok
- valós numerikus
- szöveges avagy sztring
- (egydimenziós) tömb
- erősen típusos regex (@/REGEX/)
A tömböt leszámítva mindegyik skalár típus.
Minden változó típusa dinamikus, azaz a használattól függően változik. Egy változó típusát az értéke határozza meg.
Tömb típusú változót viszont nem lehet később skalár értékek tárolására használni!
Az AWK - a BASH-sel ellentétben - nem érzékeny a szóközökre, ahogy a C nyelv sem.
EMLÉKEZTETŐ: Nem teszünk $-t a változók neve elé!
Operátorok
A relációs és logikai operátorokat (pl. ~, ==, <, ||) az A1 anyagrészben megismertük.
Aritmetikai operátorok: +, -, *, /, %, ^, **
Mivel minden szám lebegőpontos, a '/' osztás művelet is mindig az.
Maradékképzésnél (%) ha az osztandó negatív, az eredmény is negatív lesz. Például -17 % 8 eredménye -1.
Hatványozásra a POSIX szabvány csupán a '^' karaktert definiálja, de gawk-ban létezik a (BASH-ben is használt) '**' operátor.Értékadás operátorok: =, +=, -=, *=, /=, %=, ^=, **=
Az eredményt az első operandusban tárolják el. Így például az x = x+y művelet x += y alakban is írható.Inkrementálás és dekrementálás operátorok: ++, --
Rendre 1-gyel növeli és csökkenti a változó értékét. Mindkét művelet prefix (pl. ++x) és postfix (pl. x--) alakban is használható, ahogy C-ben.
Sztringek összefűzése
A konkatenáció művelet AWK-ban is az összefűzendő értékek egymás után írásán alapul. Két fontos eltérés van a BASH-ben használatos módszertől:
- A szöveg konstansokat mindig idézőjelek közé kell tenni.
- Szöveges változók közé üres sztringet vagy szóközt kell tenni a helyes működés érdekében.
Példa:
#!/bin/gawk -f
BEGIN {
s1 = "kecske"
s2 = "sajt"
s3 = s1""s2"os" # Így is jó: s3 = s1 s2 "os"
print s3, "saláta"
print s3" pogácsa"
}
Kimenet:
kecskesajtos saláta kecskesajtos pogácsa
Vezérlési szerkezetek
Szelekciós vezérlés: if - else
if (FELTÉTEL){
UTASÍTÁSOK
} else if (FELTÉTEL){
UTASÍTÁSOK
} else{
UTASÍTÁSOK
}
Esetkiválasztásos vezérlés: switch (gawk specifikus, nem lesz számonkérve!)
switch (KIF) {
case érték VAGY reguláris kifejezés:
UTASÍTÁSOK
case érték VAGY reguláris kifejezés:
UTASÍTÁSOK
.
.
.
default:
UTASÍTÁSOK
}
Előfeltételes ismétléses vezérlés: while
while (FELTÉTEL){
UTASÍTÁSOK
}
Végfeltételes ismétléses vezérlés: do-while
do {
UTASÍTÁSOK
} while (FELTÉTEL)
Számlálásos ismétléses vezérlés: for
for (KIF1;KIF2;KIF3){
UTASÍTÁSOK
}
Diszkrét ismétléses vezérlés: listás for
for (INDEX in NÉV){
UTASÍTÁSOK
}
Az INDEX változó sorban felveszi a NÉV nevű tömb elemeinek indexét, miközben a megadott utasítások végrehajtódnak.
Néhány beépített változó
$0 - Az aktuális rekord/sor.
$1, $2, $3, …, $NF - Az aktuális rekord mezői/szavai.
A mező sorszáma matematikai kifejezés eredménye is lehet. Például ha i = 4, $(i+1) az 5. mező értéke lesz.NF - Number of Fields, vagyis a mezők száma az aktuális rekordban.
NR - Number of Records, az eddig látott rekordok száma, azaz a jelenlegi rekord sorszáma. Nem az összes rekord darabszáma, mivel azt nem ismerjük, míg végig nem értünk a fájlon.
FNR - Több fájl esetén a feldolgozás alatt álló fájl aktuális sorának azonosítója. Ha csak egy fájl van, FNR == NR mindig teljesül.
FILENAME - A feldolgozás alatt álló fájl neve.
FS - Field Separator, mező elválasztó szöveg. Alapértelmezés szerint szóköz, ekkor nem érzékeny a több egymást követő whitespace karakterre (pl. szóköz, tabulátor).
A BASH-ben megismert cut paranccsal ellentétben több karakterből is állhat. Sőt, akár reguláris kifejezés is lehet.OFS - Output FS, kimeneti mező elválasztó szöveg. Alapértelmezés szerint szóköz, de akár több karakterből is állhat. A print utasítás argumentumai között kerül kiíratásra.
RS - Record Separator, rekord elválasztó karakter. Alapértelmezett értéke a '\n' sortörés karakter, de gawk-ban akár regex is lehet.
ORS - Output RS, kimeneti rekord elválasztó szöveg. Alapból ez is a '\n' sortörés karakter, de több karakterből is állhat (pl. két sortörés karakterből). A print utasítás legvégén kerül kiíratásra.
Ugró utasítások
break, continue - Kilépés a ciklusból, ill. rátérés a ciklus következő iterációjára. Mindig a legbelső ciklusra vonatkoznak, amelyben szerepelnek.
exit - A bemenet feldolgozásának azonnali befejezése. Ha nem az END blokkon belül használjuk, akkor az esetleges END minta akciója végrehajtódik, különben a program rögtön befejezi működését.
next - Azonnal befejezi az aktuális rekord feldolgozását, s a következőre ugrik a legelső szabály/blokk mintáját tesztelve.
nextfile - Azonnal befejezi az aktuális fájl feldolgozását, s a következő első rekordjára ugrik a legelső szabály/blokk mintáját tesztelve.
Példa:
#!/bin/gawk -f
# Az alábbi program addig adja össze a páros sorokban található számokat, amíg el nem éri a 256-os összeget.
# Ha az adott sorban 17-tel osztható számot lát, akkor egyből a következő rekordra ugrik.
# A végén kiírja az így kapott összeget, és a meglátogatott (páros indexű) sorok darabszámát.
BEGIN {
# Kezdőértékek beállítása.
# A 0-ra inicializálás elhagyható, mert a változó első használatakor impliciten üres sztringre vagy nullára állítódik.
osszeg = 0
sorok = 0
}
NR%2 == 0 {
# Ennyi sort dolgoztunk fel eddig.
sorok++
# Az aktuális rekord mezőit for ciklussal tudjuk bejárni.
# A ciklusváltozót 1-től NF-ig növeljük, mert az első mező indexe 1, az utolsóé pedig a mezők darabszáma.
for(i=1;i<=NF;++i){
# Ha osztható 17-tel, akkor ugrás a következő rekordra.
if($i%17 == 0)
next
osszeg += $i
# Ha az összeg elérte a 256-os értéket, ugrás az END blokkba.
if(osszeg >= 256)
exit
}
}
END {
print "A kapott összeg: " osszeg
printf("A feldolgozott sorok száma: %d\n", sorok)
}
Feladatok
1. Írj AWK szkriptet, amely kiszámítja a bemeneti fájl első oszlopában lévő értékek összegét és átlagát!
Elvárt kimenet a szamok1.txt fájlra:
Összeg: 1
Átlag: 0.125000
2. Írj AWK szkriptet, amely egy olyan fájlt kap bemenetként, melynek minden sorában tetszőleges, de legalább egy darab egész szám szerepel, méghozzá ";"-vel elválasztva!
Számítsd ki (külön-külön) minden sornak az átlagát, a végén pedig az összes szám átlagát is írasd ki!
Elvárt kimenet a szamok2.txt fájlra (a kiíratás sorrendje tetszőleges):
0.5
42
9.25
-16
Összesített átlag: 5.333333
3. Írj AWK szkriptet, amely a bemeneti fájl azon rekordjait írja ki, melyek első mezője nem egyezik meg az előző sor első mezőjének értékével!
Elvárt kimenet a szoveg.txt fájlra:
szoveg szoveg szoveg
szöveg Az ékezet miatt ez is jó.
valami
na ez már valami
OS is Life!
elégséges közepes
közepes
jeles OK
4. Írj AWK szkriptet, amely a bemeneti fájlok utolsó sorát írja ki, méghozzá a gawk specifikus ENDFILE minta nélkül!
Elvárt kimenet az ekezetes_sorszamok.txt és ekezetes_szamok.csv fájlokra:
tizedik
tíz;2
A3
Dinamikus reguláris kifejezések
(Kiegészítő anyag, nem lesz számonkérve!)
- A '~' és '!~' operátorok használatakor nem csak /REGEX/ konstansokra illeszkedést vizsgálhatunk, hanem tetszőleges szöveges kifejezést beilleszthetünk.
- A regex konstansokat viszont mindenképpen perjelek között érdemes megadni, mert dinamikus regexekben a speciális karakterek escape-eléséhez dupla '\' karakter szükséges. Részletesebben lásd a GNU AWK dokumentációját.
- Ez a funkció számos programozási nyelvben elérhető, pl. Python-ban, Javascript-ben, Matlab-ban.
Példa:
#!/bin/gawk -f
BEGIN {
minta = "sajt"
szoveg = "kecskesajtsajtsajt maraton"
print "A \"kecskesajtsajtsajt maraton\" szöveg:\n"
if (szoveg !~ minta"{3,}")
printf("NEM ")
print "illeszkedik a \"sajt{3,}\" regexre,"
if (szoveg !~ "("minta"){3,}")
printf("NEM ")
print "illeszkedik a \"(sajt){3,}\" regexre."
}
Kimenet:
A "kecskesajtsajtsajt maraton" szöveg: NEM illeszkedik a "sajt{3,}" regexre, illeszkedik a "(sajt){3,}" regexre.
Tömbök
Vegyesen szöveges és numerikus elemek együttes tárolására használhatók. Minden tömbelemet egy-egy kulcs-érték pár reprezentál, ahol kulcs a tömb indexe.
AWK tömbök tulajdonságai:
- Egydimenziós tömbök létrehozárása van lehetőség, bár gawk-ban többdimenziós tömbök definiálása is támogatott.
- Nem kell előre megadni a tömb méretét, vagyis dinamikus.
- Nem csak számok lehetnek az indexek, hanem akár szöveg is. Valójában mindig szövegként vannak kezelve az indexek, tehát ASSZOCIATÍV TÖMBről beszélünk.
- Vegyesen tartalmazhat numerikus és szöveges értékeket.
NÉV[INDEX]
- A megadott indexű tömbelem aktuális értékét jelöli.
NÉV[INDEX] = ÉRTÉK
- Értékadás egy létező tömbelemnek, vagy új elem beszúrása.
- Ha eddig a tömb nem létezett, létrehozza azt.
- A C programozási nyelv egyéb értékadó, növelő és csökkentő műveletei is használhatóak.
INDEX in NÉV - Ez a logikai művelet csak akkor igaz, ha a NÉV tömbnek van INDEX indexű eleme. Ha for ciklus fejlécében használjuk, egyesével végigmegy a tömb indexein. Tagadásakor zárójelezni kell, vagyis !(INDEX in NÉV) alakban írandó.
delete NÉV[INDEX] - A megadott indexű tömbelem törlése. Nem dob hibát, ha a megadott tömbelem nem létezik.
delete NÉV - A tömb összes elemének törlése. Vigyázat, a tömb továbbra is létezni fog, csak üres lesz! Nem dob hibát, ha a megadott néven nem létezik tömb.
Szövegkezelő függvények
Az összefűzésen kívül számos további művelet végezhető el sztringekkel különböző beépített függvények segítségével. Ezek közül néhány:
sprintf(FORMÁTUM[, LISTA]) - A printf utasításhoz hasonlóan formázott szöveg előállítására szolgál, az eredményt visszatérési értékként kapjuk meg (kiíratás helyett).
length(SZÖVEG) - A megadott sztring hossza karakterekben. Amennyiben paraméter nélkül használjuk, akkor az aktuális rekord hosszát adja vissza. Gawk-ban tömb méretét (elemeinek számát) is lekérdezhetjük vele.
index(SZÖVEG, RÉSZ) - A RÉSZ szöveg legelső előfordulásának pozíciója SZÖVEGben. Ha nincs találat, akkor nullát ad vissza.
split(SZÖVEG, TÖMB, HAT) - A SZÖVEGet a HAT határolójel mentén darabokra bontja, a darabokat a megadott tömbben eltárolja, majd visszaadja a darabok számát. A SZÖVEG változatlan marad. A tömb elemei a darab sorszámával lesznek indexelve, az első darab indexe 1. HAT reguláris kifejezés is lehet.
substr(SZÖVEG, IND[, HOSSZ]) - A SZÖVEG IND sorszámon kezdődő részét adja vissza. Három paraméter megadása esetén legfeljebb HOSSZ karakterből álló részt ad vissza. Például a substr(SZÖVEG, k+1) hívás levágja a SZÖVEG első k darab karakterét, a k. karaktert pedig a substr(SZÖVEG, k, 1) utasítással kaphatjuk meg.
tolower(SZÖVEG) - Visszaadja a SZÖVEG kisbetűssé konvertált értékét. A felismert betűk halmaza az LC_CTYPE környezeti változótól függ.
toupper(SZÖVEG) - Visszaadja a SZÖVEG nagybetűssé konvertált értékét. A felismert betűk halmaza az LC_CTYPE környezeti változótól függ
Megjegyzés: A pythonos Coursera tanfolyamban látható, hogy pythonban a zárójelezést regexekben az illeszkedő szövegrészek megfelelő szakaszainak kinyerésére is használhatjuk. Ezt a funkciót AWK-ban a match beépített függvény biztosítja, azonban jelen kurzuson nem tárgyaljuk.
1. példa:
#!/bin/gawk -f
BEGIN {
szoveg = "Kimaxolom;az;OS;2.;ZH-t."
printf("Az eredeti szöveg: %s\n\n", szoveg)
print "\"OS\" kezdőpozíciója: " index(szoveg,"OS")
print "A szövegem hossza: " length(szoveg)
split(szoveg,T,";")
print "A szövegem \";\" mentén feldarabolva, és a T tömbbe mentve:"
for(i in T){
printf("%s ",T[i])
}
printf("\n")
print "A szöveg az 5. pozíciótól: " substr(szoveg, 5)
print "A szövegem az 5. pozíciótól 4 karakter hosszan: " substr(szoveg, 5, 4)
print "Kisbetűsítve: " tolower(szoveg)
print "Nagybetűsítve: " toupper(szoveg)
}
Kimenet:
Az eredeti szöveg: Kimaxolom;az;OS;2.;ZH-t. "OS" kezdőpozíciója: 14 A szövegem hossza: 24 A szövegem ";" mentén darabolva, és a T tömbbe mentve: Kimaxolom az OS 2. ZH-t. A szövegem az 5. pozíciótól: xolom;az;OS;2.;ZH-t. A szövegem az 5. pozíciótól 4 karakter hosszan: xolo Kisbetűsítve: kimaxolom;az;os;2.;zh-t. Nagybetűsítve: KIMAXOLOM;AZ;OS;2.;ZH-T.
2. példa:
Tekintsük a tomb_teszt.txt tesztfájlt, melynek tartalma:
everything is awesome EVERYTHING is cool everything is working OS is easy
Vegyük észre, hogy általában több szóköz választja el a szavakat. Alapértelmezett (szóköz) mezőelválasztó esetén ez nem okoz gondot az AWK-nak, helyesen mezőkre bontja a rekordokat.
#!/bin/gawk -f
{
# Minden különböző szó számára új elemet hoz létre a "szavak" tömbbe.
# Az előforduló mezők az indexek (ezek szigorúan egyediek!), s értéküket fixen 1-re állítja.
for(i = 1; i <= NF; ++i)
szavak[$i] = 1
}
END {
# A tömb mérete megegyezik a különböző szavak számával.
# A kis- és nagybetűk megkülönböztetése miatt az "everything" és az "EVERYTHING" különbözőnek számít.
# Az eredmény mindkét alábbi esetben 8 az előző tesztfájlra.
# Végigmegy a tömbön, hogy megszámolja az elemeit.
for(i in szavak) ++darab
print darab
# Gawk-ban a length() függvénnyel is megkaphatjuk egy tömb méretét.
print length(szavak)
}
Numerikus függvények
Számokon végezhető műveletekre is vannak beépített függvények. A többségük alább listázva:
sin(rad), cos(rad), atan2(rad1, rad2) - Trigonometrikus függvények. A szöget minden esetben radiánban kell megadni.
Az atan2 függvény rad1/rad2 arkusz tangensét adja eredményül. ℼ értékét megkaphatjuk az atan2(0, -1) hívással.sqrt(KIF) - Gyökvonás.
exp(KIF), log(KIF) - Természetes (e-alapú) exponens és logaritmus.
int(KIF) - Egésszé konvertálás csonkolással (truncation). Korlátozott mértékben a vezető nullák eltávolítására is képes.
Feladatok
1. Írj AWK szkriptet, amely egy általad meghatározott szövegrészletet keres az adott fájlban, és megszámolja, hány sorban volt illeszkedés!
A keresett sztringet egy regex nevű változón keresztül add át paraméterben a szkriptnek a -v kapcsoló segítségével! Pl.: ./feladat.awk -v regex="os" post.txt
Elvárt kimenet az előző példára:
Illeszkedő sorok száma: 8
2.* Változtasd meg az előző feladat megoldását úgy, hogy a regex változón keresztül átadott sztringre illeszkedő mezőket számolod meg, és a mezők elején és végén nem megengedett az illeszkedés!
Elvárt kimenet a post.txt fájlra regex="os" esetén:
Illeszkedő mezők száma: 7
Elvárt kimenet a post.txt fájlra regex="a" esetén:
Illeszkedő mezők száma: 46
3. Írj AWK szkriptet, amely egy, az ls -l parancs egy lehetséges kimenetét tartalmazó fájlt kap bemenetként! Számold meg, hogy az egyes felhasználók hány állományt hoztak létre!
Elvárt kimenet az ls-l.txt fájlra (a kiíratás sorrendje tetszőleges):
Jonas: 4
Dezso: 5
Bela: 7
Geza: 5
4.** Írj AWK szkriptet, amely egy, soronként egy-egy egész számot tartalmazó fájlt vár paraméterben! Állítsd elő az 1-nél nagyobb számok prímtényezős felbontását az alábbi minta alapján!
Elvárt kimenet a primfelbontas.txt fájlra:
1001 = 7 * 11 * 13
5 = 5
16 = 2^4
288 = 2^5 * 3^2
513 = 3^3 * 19
1002 = 2 * 3 * 167
999999 = 3^3 * 7 * 11 * 13 * 37
7203 = 3 * 7^4
929 = 929
51100 = 2^2 * 5^2 * 7 * 73
625 = 5^4
151959 = 3 * 37^3
9376 = 2^5 * 293
769318 = 2 * 11^3 * 17^2
További gyakorlófeladatok
Cservenák Bencétől: feladatlap, tesztfájlok és egy lehetséges megoldás
Figyelem! Az előző feladatsor a 2020-as anyagrészhez van igazítva, akkor készült a videósorozat is. Az aktuális anyagot nem fedi le teljesen!
BASH és AWK kód szintaxis kiemelő stílus csere:
Sötét alapon közepesen világos karakterek.
Fehér alapon sötét karakterek (ez az alapértelmezett).