=====Szűrők=====
A szűrő funkciókat megvalósító parancsok a bemenetükre érkező adatokkal valamit csinálnak, majd az eredményt megjelenítik. A GNU/Linux rendszerben a konfigurációs állományok is jellemzően szöveges fájlok ezért ezek a parancsok a rendszer adminisztrációját is segítik.
====A cat parancs====
Bár a **cat** parancs a fenti értelemben nem szűrő, hiszen a bemenetére érkező adatokkal nem csinál semmit, mégis ide soroljuk. Ezzel a paranccsal megjeleníthetjük szöveges fájl tartalmát, létrehozhatunk fájlt, fájlhoz hozzáfűzhetünk és állományokat is egyesíthetünk vele.\\
Az alábbi parancs a gyumolcs.txt állományt hozza létre az utána beírt sorok tartalmával. A Ctrl+D billentyűkombináció a beírás végét jelenti.
palferi@lizi:~$ cat > gyumolcs.txt
alma
körte
szilva
eper
alma
barack
eper
+D
A két > jellel hozzáfűzhetünk sorokat a meglévő fájlhoz:
palferi@lizi:~$ cat >> gyumolcs.txt
szőlő
eper
+D
A vágólap tartalmát is be tudjuk illeszteni így egy fájlba. GNOME Terminál esetén Szerkesztés menüpont Beillesztés, vagy Ctrl+Shift+v billentyűkombinációval.\\
Nem csak szöveges állományokat egyesíthetünk a **cat** paranccsal, hanem pl. mp3 formátumú fájlokat is:
palferi@lizi:~$ cat track01.mp3 track02.mp3 track03.mp3 > track01-03.mp3
palferi@lizi:~$ file track01-03.mp3
track01-03.mp3: MPEG ADTS, layer III, v1, 128 kbps, 44.1 kHz, Stereo
palferi@lizi:~$ ls -lh *.mp3
-rw-rw-r-- 1 palferi palferi 13M dec 27 15:30 track01-03.mp3
-rw-r--r-- 1 palferi palferi 4,0M júl 31 2007 track01.mp3
-rw-r--r-- 1 palferi palferi 5,0M júl 31 2007 track02.mp3
-rw-r--r-- 1 palferi palferi 3,3M júl 31 2007 track03.mp3
A fenti parancsokkal a három zenei fájlt egyesítettük a track01-03.mp3 fájlba, lekérdeztük a tulajdonságait az új fájlnak a ''file'' paranccsal. Végül a részletes listán látjuk, hogy az új fájl mérete valóban az eredeti három összegével egyenlő.
====A grep parancs====
A leggyakrabban használt szűrő parancs. Adott mintát tartalmazó sorokat jelenít meg. Szintaxisa:\\
grep [ kapcsolók ] minta [ fájl ... ]
Fontosabb kapcsolók:
^ Kapcsoló ^ Jelentés ^
| -E |A grep bővített kifejezésekkel dolgozik (az egrep esetében nem kell megadni)|
| -e minta | A mintát így is meg lehet adni. Feltétlenül így kell megadni, ha a minta – jellel kezdődik, pl.: egrep -e '-q' file |
| -i | Kis és nagybetű közti különbség nem számít|
| -l | Ha több állományban keres, kiírja azok neveit amelyben megvan a minta|
| -n | A találat elé kiírja annak sorszámát|
| -v | Inverz kiírás: azokat a sorokat írja ki amelyekben nem volt illesztés|
| -w | Csak azokat a karakterláncokat tekinti találatoknak amelyek teljes szót alkotnak (szó elválasztó van a két szélükön, és a szó számokból, betűkből és _ karakterekből épül fel|
Néhány példa:\\
**1.** Az /etc/passwd állomány azon sorai, amelyekben van **usb** szöveg:
palferi@lizi:~$ grep usb /etc/passwd
usbmux:x:108:46:usbmux daemon,,,:/home/usbmux:/bin/false
Látjuk, hogy egy ilyen sor van.\\
\\
**2.** Az /etc/passwd állomány azon sorai, amelyekben van **usb** szó:
palferi@lizi:~$ grep -w usb /etc/passwd
Nem jelent meg semmi. Nincs ilyen sor, hiszen az usbmux szó szerepel a fenti sorban nem az usb.\\
\\
**3.** Az /etc/passwd állomány azon sorai, amelyekben nem szerepel a **false** szöveg:
palferi@lizi:~$ grep -v false /etc/passwd
**4.** Az /etc/passwd állomány azon sorai és azok sorszáma, amelyekben szerepel a **user** szöveg:
palferi@lizi:~$ grep -n user /etc/passwd
32:hplip:x:113:7:HPLIP system user,,,:/var/run/hplip:/bin/false
41:dovenull:x:121:65534:Dovecot login user,,,:/nonexistent:/bin/false
====A sort parancs====
A **sort** parancs a bemenetre érkező adatokat rendezi. Fontosabb kapcsolói:
| -r | fordított rendezés|
| -i | Kis és nagybetű közti különbség nem számít|
| -n | Numerikus rendezés |
Jelenítsük meg rendezetten a gyumolcs.txt tartalmát:\\
palferi@lizi:~$ sort gyumolcs.txt
alma
alma
barack
eper
eper
eper
körte
szilva
szőlő
====Az uniq parancs====
Az **uniq** parancs a szomszédos egyező sorok szűrésére szolgál. Az ismétlődő sorokat csak egyszer jeleníti meg. A szemléltetéshez a ''sort''-al rendezett új állományt hozunk létre:
palferi@lizi:~$ sort gyumolcs.txt > gyumolcs_rend.txt
palferi@lizi:~$ uniq gyumolcs_rend.txt
alma
barack
eper
körte
szilva
szőlő
A **c** kapcsolóval az előfordulás számát is megjeleníthetjük:
palferi@lizi:~$ uniq -c gyumolcs_rend.txt
2 alma
1 barack
3 eper
1 körte
1 szilva
1 szőlő
====Az cut parancs====
A **cut** paranccsal meghatározott karakterekkel határolt szövegmezőket, vagy bizonyos pozíciójú karaktereket vághatunk ki szövegsorokból. A -f kapcsolóval az mezők sorszámát, a -d kapcsoló pedig az elválasztó karaktert adhatjuk meg. A pozíciók megadásánál a -c kapcsolót használjuk.\\
A fenti példákban láttuk, hogy az ''/etc/passwd'' állomány minden sora '':'' karakterrel elválasztott mezőket tartalmaz. A cut paranccsal jelenítsük meg az első és a hetedik mezőt:
palferi@lizi:~$ cut -f 1,7 -d":" /etc/passwd
root:/bin/bash
daemon:/bin/sh
bin:/bin/sh
sys:/bin/sh
sync:/bin/sync
...
A következő példában ugyanebből a fájlból minden sor 5-10 és 17 sorszámú karakterét jelenítjük meg:
palferi@lizi:~$ cut -c 5-10,17 /etc/passwd
:x:0:0/
on:x:1m
x:2:2:i
x:3:3:e
:x:4:6y
...
====Az nl parancs====
Az **nl** paranccsal sorszámozva jeleníthetjük meg a fájlokat.\\
Jelenítsük meg sorszámozva a ''elso.sc'' szkriptet:
palferi@lizi:~$ nl ./proba/elso.sc
1 #!/bin/bash
2 echo -n "Adja meg a nevét: "
3 read NEV
4 clear
5 sleep 3
6 echo "Az Ön neve: $NEV"
====A tac parancs====
A **tac** parancs a bemenetére érkező szöveget fordított sorrendben írja ki, az első sor az utolsó lesz. (A ''tac'' szó a ''cat'' fordítottja) Az ''elso.sc'' fájl a ''tac''-al kiíratva:
palferi@lizi:~$ tac ./proba/elso.sc
echo "Az Ön neve: $NEV"
sleep 3
clear
read NEV
echo -n "Adja meg a nevét: "
#!/bin/bash
====A rev parancs====
A **rev** parancs egy sor karaktereinek sorrendjét fordítja meg. Az ''elso.sc'' fájl a ''rev''-el kiíratva:
palferi@lizi:~$ rev ./proba/elso.sc
hsab/nib/!#
" :téven a gem ajdA" n- ohce
VEN daer
raelc
3 peels
"VEN$ :even nÖ zA" ohce
====A head parancs====
A **head** parancs a bemenetére kerülő szöveges fájlból annyi sort jelenít meg, amennyit opcióként megadunk. Opció nélkül tízet.
palferi@lizi:~$ head -2 gyumolcs.txt
alma
körte
====A tail parancs====
A **tail** parancs a bemenetére kerülő szöveges fáj végéről annyi sort jelenít meg, amennyit opcióként megadunk. Opció nélkül tízet. Hasznos lehet még a -f opció, ami a fájl növekedése során hozzáfűzött adatok kiírására szolgál.
palferi@lizi:~$ tail -2 gyumolcs.txt
szőlő
eper
Hasznos lehet még a -f opció, ami a fájl növekedése során hozzáfűzött adatok kiírására szolgál.
palferi@lizi:~$ tail -f /var/log/syslog
Dec 27 12:23:06 lizi kernel: [0.878101] sd 0:0:0:0: [sda] 234441648 512-byte logical blocks: (120 GB/111 GiB)
...
A kiíratás leállítása: Ctrl+c
=====Csővezetékek=====
A csővezetékek kommunikációs csatornák, amelyeken keresztül egy folyamat kimenete egy másik bemenetére irányítható. A csővezeték (angolul pipe) jele a |. Az alábbi példában a ''cat'' kimenetét a ''sort'' standard bemenetére irányítjuk:
palferi@lizi:~$ cat gyumolcs.txt | sort
alma
alma
barack
eper
eper
eper
körte
szilva
szőlő
Több csővezetéket is alkalmazhatunk. Az alábbi példában sorba rendezzük, az ismétlődő sorokat elrejtjük és sorszámozunk:
palferi@lizi:~$ cat gyumolcs.txt | sort | uniq | nl
1 alma
2 barack
3 eper
4 körte
5 szilva
6 szőlő
Itt pedig a szavakat is megfordítjuk:
palferi@lizi:~$ cat gyumolcs.txt | sort | uniq | rev | nl
1 amla
2 kcarab
3 repe
4 etrök
5 avlizs
6 őlőzs
====Feladat====
Jelenítse meg a képernyőn a ''gyumolcs.txt'' fájl utolsó előtti sorát.
palferi@lizi:~$ tail -2 gyumolcs.txt | head -1
szőlő
====Az tr parancs====
A **tr** parancs a bemenetére érkező szöveget a kimenetre írja, de a kiírás előtt karaktereket cserél vagy töröl. Fontosabb kapcsolói:
| -d | a megadott karaktereket törli|
| -s | A megadott ismétlődő karaktereket törli|
Jelenítsük meg a gyumolcs.txt tartalmát az **a** és **e** betűt felcserélve:
palferi@lizi:~$ cat gyumolcs.txt | tr ea ae
elme
körta
szilve
apar
elme
bereck
apar
szőlő
apar
Az alábbi parancs töröi az **e** és az **m** ismétlődését:
palferi@lizi:~$ echo eemmmeeeel | tr -s em
emel
Hasznos lehet a fölösleges szóközök eltávolításában, esetleg más elválasztó karakterre cserélésben. Az alábbi példa törli az ismétlődő szóközöket, majd :-re cseréli őket:
palferi@lizi:~$ echo "Ede 17 42000" | tr -s " "| tr " " :
Ede:17:42000
A napjainkban elterjedt UTF-8-as környezetben a **tr** parancs a magyar ékezetes karaktereket nem kezeli megfelelően. Ilyen esetekben a **sed** program használata javasolt.
=====Reguláris kifejezések=====
A reguláris kifejezések segítségével mintákat határozhatunk meg, amikkel kereshetünk vagy más szövegek feldolgozásához köthető feladatokat oldhatunk meg. Gyakran regexp-nek vagy regex-nek is nevezik az angol regular expression kifejezés alapján. A reguláris kifejezésben karakterek és metakarakterek (speciális karakterek pl.: ''.*[\]^$'') találhatóak.\\
A reguláris kifejezéseknek több változata is létezik. Alapszintű kifejezéseket (basic, BRE) a régi programokkal (expr, grep, sed) való kompatibilitás miatt használunk. A bővített kifejezéseket (extended, ERE) az **egrep** vagy **grep -E**, az **awk** programokban és különböző programozási nyelvekben használnak.\\
Ebben a fejezetben az **egrep** vagy **grep -E** programban használható reguláris kifejezésekről lesz szó. A bemutatott kifejezések többsége a **grep** paranccsal is használható, az alábbi metakarakterek kivételével: +, ?. | és ().
====Egyedi karakter====
Az **a** kifejezés az **a** karakterre illeszkedik, ha az nem metakarakter.
Példaként jelenítsük meg azokat a sorokat a ''szamol.sc'' szkriptből, amelyek a kis L betűt tartalmaznak:
palferi@lizi:~$ cat ./proba/szamol.sc | grep 'l'
# kiszamoljuk
echo "A nullával való osztás étrelmetlen"
else
Amennyiben olyan karakterre akarunk illeszkedést, ami metakarakter is, akkor a \ jelet kell elé írnunk. Például a '\*' illeszkedik a *-ra. Példaként jelenítsük meg azokat a sorokat a ''szamol.sc'' szkriptből amelyek a ''*'' karaktert tartalmazzák:
palferi@lizi:~$ cat ./proba/szamol.sc | grep '\*'
echo "$1 * $2 = $(($1*$2))"
====. (pont) metakarakter====
A pont bármely karakterre illeszkedik. Két pont két tetszőleges karakterre. Figyeljük meg, hogy a ''e..e'' reguláris kifejezés két sorra is illeszkedik a ''szamol.sc'' fájlból:
palferi@lizi:~$ cat ./proba/szamol.sc | grep 'e..e'
echo "A nullával való osztás étrelmetlen"
else
====* (csillag) metakarakter====
A * előtt álló karakter akárhányszor ismétlődhet. Akát nullaszor is! Ezért először talán furcsa, hogy az 'a*' kifejezés illeszkedik a bbb szövegre:
palferi@lizi:~$ echo bbb | egrep 'a*'
bbb
Pedig a kifejezés azt jelenti, hogy akárhány **a** lehet a sorban, akár nulla is.\\
Nézzünk egy gyakorlatiasabb példát. Egy szöveges állományból azokat a sorokat kell kiszűrnünk, amelyek a ''csoport=group'' karakterekkel kezdődnek, és azokat is, melyeknél a csoport után számok vannak. Itt a
''^csoport[0-9]*=group'' kifejezést használhatjuk. Ez azt jelenti, hogy a ''csoport'' után szám következhet, akár több is, de ha nincs szám (a számok darabszáma nulla), az is megfelel a szűrőnek:
palferi@lizi:~$ echo csoport=group | egrep ^csoport[0-9]*=group
csoport=group
palferi@lizi:~$ echo csoport42=group | egrep ^csoport[0-9]*=group
csoport42=group
====Sor eleje: ^====
Ezzel a metakarakterrel meghatározhatjuk, hogy csak a sor elején illeszkedjen az utána lévő karakterre. A '^i' csak a kis **i** betűvel kezdődő sorokra illeszkedik. A ''szamol.sc'' fájlban több sor is tartalmaz **i** betűt, de csak egy sornak ez az első karakterere:
palferi@lizi:~$ cat ./proba/szamol.sc | grep '^i'
if test $2 -eq 0
====Sor vége: $====
Ezzel a metakarakterrel meghatározhatjuk, hogy csak a sor végén illeszkedjen az előtte lévő karakterre. A '''e$''' csak a kis **e** betűvel végződő sorra illeszkedik.
palferi@lizi:~$ cat ./proba/szamol.sc | grep 'e$'
else
A sor vége és a sor eleje metakaraktert horgonynak (anchor) is mondják és gyakran előfordulnak egy kifejezésben. Az alábbi reguláris kifejezés olyan sorokra illeszkedik, amelyek csak szóközt tartalmaznak:
palferi@lizi:~$ cat /etc/samba/smb.conf | grep -v '^ *$'
Itt egy konfigurációs állományt jelenítünk meg ilyen sorok nélkül ( -v kapcsoló). A kifejezést úgy értelmezhetjük, hogy a sor szóközzel kezdődik, ebből akárhány van és az utolsó is az.
====Karakter halmaz: [ ]====
Szögletes zárójelek közé írt karakterek bármelyike illeszkedik a mintára. Például az [abc] beírás az bármelyik karakterre illeszkedik a három közül. Rövidíthetünk is a ''-'' jellel: a [a-z] a kisbetűk bármelyikét jelenti, [0-9] bármelyik számjegyet.\\
Az alábbi parancs a ''/proc/cpuinfo'' fájlból azokat a sorokat jeleníti meg, melyek **b** vagy **s** betűvel kezdődnek:
palferi@lizi:~$ cat /proc/cpuinfo | grep '^[bs]'
stepping : 9
siblings : 4
bogomips : 5986.28
...
Metakarakterek saját magukat jelentik a karakterhalmazban. A [d.] olyan sorokra illeszkedik amelyekben előfordul a d karakter vagy a . (pont). Kivételt képez a második helyen lévő -, ez a rövidítést jelenti, és a ^ karakter is a halmaz első karaktereként: ez a lista ellentettjét jelenti. A [^0-9] jelentése: nem szám. A következő parancs a ''/proc/cpuinfo'' fájlból azokat a sorokat jeleníti meg, amelyek nem a-p karakterekkel kezdődnek:
palferi@lizi:~$ cat /proc/cpuinfo | grep '^[^a-p]'
vendor_id : GenuineIntel
stepping : 9
siblings : 4
wp : yes
...
====Alternálás: |====
Amennyiben két minta közül az egyik vagy másik illesztését várjuk a | metakaraktert alkalmazzuk. A ''alma|szilva'' kifejezés olyan sorokra illeszkedik, amelyek vagy az alma, vagy a szilva szót tartalmazzák.
palferi@lizi:~$ cat gyumolcs.txt | grep -E 'alma|szilva'
alma
szilva
alma
====Csoportosítás: ( )====
Zárójelekkel csoportosíthatunk karaktereket, részmintát hozhatunk létre. A részmintát, akárcsak a az egyedi karaktert atomnak nevezzük. Gyakran ismétlődések meghatározására használjuk.
====Ismétlődések====
Ismétlődő karaktereket az alábbi metakarakterekkel határozhatunk meg:
^ Nem pontos számú ismétlődést határoz meg (kvantorok) ^^
^ Metakarakter ^ Magyarázat ^
| * | az előtte álló karakter nullaszor, vagy akárhányszor ismétlődhet |
| + | az előtte álló karakter legalább egyszer vagy akárhányszor jelenik meg |
| ? | az előtte álló karakter opcionálisan, tehát egyszer sem vagy pontosan egyszer jelenik meg |
^ Pontos számú ismétlődést határoz meg ^^
| {n} |az előtte álló karakter pontosan n-szer fordul elő (n egész szám)|
| {n,} |az előtte álló karakter legalább n-szer de akárhányszor előfordulhat|
| {n,m} |az előtte álló karakter legalább n-szer de maximum m-szer fordul elő|
Az alábbi példa 4 ismétlődést keres számokból:
palferi@lizi:~$ cat /proc/cpuinfo | grep -E '[0-9]{4}'
model name : Intel(R) Core(TM) i5-3330 CPU @ 3.00GHz
cpu MHz : 1600.000
cache size : 6144 KB
bogomips : 5986.28
...
=====Feladat 1.=====
//Szűrje ki egy szöveges állomány azon sorait, amelyek csak hármassal kezdődő egész számot tartalmaznak.//\\
A megoldás ellenőrzéséhez hozzon létre egy szöveges állományt.
palferi@lizi:~$ cat > minta1.txt
334
32 4
345
37a
3,14
3
3322
Az alábbi szűrő '^3[0-9]*$' olyan sorokra illeszkedik, ahol az első karakter 3, utána tetszőleges számjegy következik, ezekből akárhány lehet, akár nulla darab is, és az utolsó karakter is ilyen.
palferi@lizi:~$ cat minta1.txt | grep '^3[0-9]*$'
334
3
3322
Egyszerűbb beírással:
palferi@lizi:~$ grep '^3[0-9]*$' minta1.txt
334
3
3322
=====Feladat 2.=====
//Jelenítse meg a képernyőn az ''/usr/share'' könyvtár összméretét és az alkönyvtárait, de csak azokat, amelyek 1MByte-nál nagyobbak. A lista csökkenő sorrendben jelenjen meg, sorszámozva.//\\
A megoldás előtt tekintsük át a ''du'' és ''sort'' parancsok rövid súgóját:
palferi@lizi:~$ du --help
palferi@lizi:~$ sort --help
Láthatjuk, hogy a du parancsot ''-h'' és ''-''''-max-depth=1'' kapcsolókkal kiadva csak az adott könyvtár alkönyvtárait írja ki és nem byte-okban, hanem közérthető formában:
palferi@lizi:~$ du -h --max-depth=1 /usr/share/
44M /usr/share/gnome
172K /usr/share/libwacom
92K /usr/share/language-selector
1,9M /usr/share/vlc
20K /usr/share/gnome-background-properties
2,6M /usr/share/gtk-doc
...
A fenti részletből is megállapíthatjuk, hogy azokat a sorokat kell kiszűrnünk a listából, amelyek számmal kezdődnek, számmal vagy tizedesvesszővel folytatódnak, ezután szám vagy számok következnek, majd **M** vagy **G** betű. A reguláris kifejések nyelvén - kezdődik: ^; számjeggyel: [1-9]; ezután számjegy vagy '','' következik: [0-9,]; ebből egy van, vagy több: +; következik M vagy G: (M|G).
palferi@lizi:~$ du -h --max-depth=1 /usr/share/ | grep -E '^[1-9][0-9,]+(M|G)'
44M /usr/share/gnome
1,9M /usr/share/vlc
2,6M /usr/share/gtk-doc
2,2M /usr/share/zlibrary
6,3M /usr/share/mime
33M /usr/share/midi
...
A fordított és közérthető rendezéshez a ''sort -rh'' parancsba irányítjuk a szűrt kimenetet, majd az ''nl'' paranccsal sorszámozunk. A megoldás tehát:
palferi@lizi:~$ du -h --max-depth=1 /usr/share/ | grep -E '^[1-9][0-9,]+(M|G)' | sort -rn | nl
1 1,4G /usr/share/
2 252M /usr/share/icons
3 120M /usr/share/doc
4 98M /usr/share/locale
5 87M /usr/share/pyshared
6 80M /usr/share/fonts
7 71M /usr/share/virtualbox
8 58M /usr/share/help
9 51M /usr/share/libreoffice
10 46M /usr/share/app-install
11 44M /usr/share/gnome
...
=====Feladat 3.=====
//Írjon szkriptet, ami ellenőrzi, hogy két paramétert kapott és azok egész számok. Nem megfelelő paraméter esetén figyelmeztessen szöveggel.//
\\
\\
Olyan reguláris kifejezést kell írnunk, ahol az első karakter lehet szám vagy - jel (negatív szám esetén), de ebből csak egy lehet. Ezt számok követhetik, és az utolsó is az: '''^[0-9-]?[0-9]+$'''
#!/bin/bash
if [ $# -eq 2 ]
then
P1=`echo $1 | grep -E '^[0-9-]?[0-9]+$'`
P2=`echo $2 | grep -E '^[0-9-]?[0-9]+$'`
if [ -n "$P1" ] && [ -n "$P2" ]
then
echo "Paraméterek rendben"
else
echo "A parameterek nem egész számok"
fi
else
echo "A paraméterek szama nem kettő"
fi
[[st-linux_alapok:st-linux_alapok|< Vissza]]