[[oktatas:linux|< Linux]] ====== Mintaillesztés ====== * **Szerző:** Sallai András * Copyright (c) 2018, Sallai András * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]] * Web: https://szit.hu ===== Bevezetés ===== A mintaillesztés szinonimája a szabályos kifejezések használata, angolosan regular expression. Néha röviden csak regex néven hivatkozunk rá. Szövegek, szövegrészekre való hivatkozásoknál használjuk. A szövegek lehetnek fájlokban, programkódban, lehetnek fájlok vagy könyvtárak nevei stb. Linux esetén elsőként a fájlok és könyvtárak kezelésénél találkozhatunk vele. Néhány regex csoport: * Unix * POSIX * PCRE ===== Minták használata (glob) ===== A mintákat parancsok argumentumaiban, scriptekben, programokban használjuk. Elsőként nézzük meg parancsok argumentumaként. Az adott parancsnak ismernie kell a mintaillesztést. Legyen a példa kedvéért az "ls" parancs. Az "ls" parancsot arra használjuk, hogy egy könyvtár tartalmát listázzuk. Az ls parancs argumentumaként megadható milyen állományt szeretnénk listázni. Ha egy konkrét állományra vagyunk kíváncsiak, ez csak ennyi: ls valami.txt De mi van akkor, ha több állományra is kíváncsiak vagyunk. Na nem mindegyikre, mondjuk csak a .txt kiterjesztésű fájlokra. Ekkor egy "*" karakaterrel egy megadhatunk egy mintát, amely azt jelenti, bármilyen karakterből több. ls *.txt Ha olyan fájlokat szeretnénk listázni, amelynek első karaktere tetszőleges, ezt követően a "kar" szó áll, .txt kiterjesztéssel a "?" karaktert használhatunk. ls ?kar.txt Ezek a legegyszerűbb Unix mintaillesztések, amelyeket úgy nevezünk: glob, vagy globbing, esetleg "Glob patterns", vagy egyszerűen csak mintaillesztés shellben. ===== Karakterosztályok ===== Néhány karakterhalmazra hivatkozhatunk szögletes zárójelek közötti megadott nevekkel, vagy intervallumok jelzésével. Az alábbi táblázat ilyen jelöléseket mutat be. ^ ASCII karakterek ^ POSIX osztályok ^ leírás ^ | [0-9] | [:digit:] | számok | | [a-z] | [:lower:] | az angol ábécé kisbetűi | | [A-Z] | [:upper:] | az angol ábécé nagybetűi | | [A-Za-z] | [:alpha:] | az angol ábécé betűi | | [A-Za-z0-9] | [:alnum:] | az angol ábécé betűi és számok | | [0-9A-Fa-f] | [:xdigit:] | hexadecimális | | [A-Za-z0-9_] | [:word:] | ábécé, számok és aláhúzás | | [\t] | [:blank:] | szóköz vagy tabulátor | | [ \t\n\r\f\v] | [:space:] | white space karakterek | | [\x00-\x1F\x7F] | [:cntrl:] | kontrollkarakterek | | [\x00-\x7F] | [:ascii:] | ASCII karakter | | | [:graph:] | nyomtatható karakterek, kivéve a szóköz | | | [:print:] | nyomtatható karakterek és a szóköz | | | [:punct:] | nyomtatható karakterek a betűk és a számok kivételével | Az ls parancs is ismeri a karakterosztályokat. ls 01[0-9]vmi.txt A következő meghatározás egyenértékű: ls 01[[:digit:]]vmi.txt Olyan fájlokra illeszkedik, amely 01-gyel kezdődik, a harmadik karakter 0 és 9 közötti számjegy, majd "vmi.txt"-re végződik. ls 01[[:digit:]a]vmi.txt Ebben az esetben a harmadik karakter egy szám vagy egy "a" betű lehet. Ha második karakter nem csak 1 lehet, hanem lehet más szám is, meghagyva az első változatot: ls 0[0-9][0-9]vmi.txt Ebben az esetben a második és a harmadik karakter is bármilyen szám lehet. A szögletes zárójelek közötti rész, láthatjuk, hogy mindig egyetlen karakterre vonatkoznak. Másik karakter számára másik szögletes zárójelpárt kell megadnunk. Tegyük fel, hogy a második karakter esetén csak 1 és 3 elfogadott számjegy: ls 0[1-3][0-9]vmi.txt A három számjegyet egyszerűen fel is sorolhatom egymás után: ls 0[123][0-9]vmi.txt A sorrend mindegy, a következő ugyanazt jelenti: ls 0[312][0-9]vmi.txt Tegyük fel, hogy a második helyen az elfogadott számok a 1,2,3,7. Egytől háromig le lehet írni egy intervallumot, de a 7 messze áll ettől. Megadhatunk egy intervallumot, mellette más karaktereket: ls 0[1-37][0-9]vmi.txt Térjünk vissza egy egyszerűbb feladathoz. Jelenítsük meg azokat a fájlokat, amelyek "01"-gyel kezdődnek, harmadik karaktere 5 vagy 6, végződésük "vmi.txt": ls 01[5-6]vmi.txt Tegyük fel, hogy most azokat az állományokat szeretném, amelyek harmadik karaktere nem 5 és nem hat, ha nem valami más. Ha csak számok lehetnek ez leírható így: ls 01[1-47-9]vmi.txt Ha más karaktere is, akkor már: ls 01[1-47-9A-Za-z]vmi.txt De sokkal egyszerűbb egy felkiáltójellel: ls 01[!5-6]vmi.txt A szögletes zárójelen belül a felkiáltójel azt jelenti, hogy akkor van illeszkedés, ha nem a zárójelben lévő karakterek vannak a fájlnévben. Ez persze több mint a maradék szám és betűk, ebbe beletartozik minden nyomtatható és nem nyomtatható karakter. ===== A grep ===== A fentieknél összetettebb szűrés érhető el a grep vagy az egrep szűrőkkel. Tegyük fel, hogy még mindig az ls kimenetével szeretnénk dolgozni. A feladat szerint a harmadik karakter bármilyen karakter lehet. ls | grep 01.vmi.txt A fenti parancs majdnem a megfelelő megoldást adja. Azonban ha van egy olyan állományunk, amelynek a neve: "011vmiatxt", vagy 012vmiatxt, esetleg 012vmibtxt, azokra is illeszkedni fog. A grep esetén a mintaillesztés egy másik világába jutunk. A pont itt egyetlen karaktert jelöl, ami bármi lehet. Ez ha 011vmiatxt állomány nevében a kiterjesztést elválasztó pont helyett egy másik betű van, akkor arra is illeszkedik. A pontnak tehát egy speciális szerepe van. De mi van akkor ha már pedig én csak az olyan fájlokat szeretném, ahol txt kiterjesztés előtt pont van. Mivel a pont speciális használatban van ezért az csak escape szekvenciaként adható meg. Escape szekvencia a "\" visszaperjel karakterrel adható meg. Ilyenkor muszáj aposztrófok közzé tenni a szöveg: ls | grep '01.vmi\.txt' A 01 utáni pont után, harmadik karakterként bármilyen karakter állhat. A txt kiterjesztés előtt viszont csak "." pont. Mivel a harmadik karakter nem csak szám lehet ezért a fenti kifejezés illeszkedik a 01vvmi.txt állományra is. Ha itt is csak számokat szeretnénk akkor az megoldható az eddigiek szerint: ls | grep '01[0-9]vmi\.txt' De mint láttuk, ha csak a számokat szeretnénk, ehhez nem kell a grep szűrő. ===== Kiterjesztett lehetőségek ===== A grep a -E kapcsolóval, vagy önmagában az egrep a szabályos kifejezések kiterjesztett változatát képes használni. Itt lehetőség nyílik a például egyszerű zárójelekkel szavak megadása. Tegyük fel, hogy szeretnénk látni 011vmi.txt és 011vki.txt állományokat is, ha azok léteznek. ls | egrep '011(vmi|vki)\.txt Egy új operátort is használunk ez a "|" pájp karakter. Ez VAGY kapcsolatot fejez ki. Az állomány akkor lesz listázva, ha a "011" és a ".txt" között vagy a "vmi" vagy a "vki" szó szerepel. A grep a -E kapcsolóval ugyanerre az eredményre vezet: ls | grep -E '011(vmi|vki)\.txt ===== A sor eleje és vége ===== Ha egy "a" betűt írok mintának, az ls | grep parancsok kettős parancs számára, akkor minden olyan fájl meg fog jelenni, amelyben legalább egy "a" betű szerepel bárhol a fájlnévben. ls | grep a Meghatározhatunk illeszkedést a sor elejére a "^" karakterrel. Legyen a minta "^a": ls | grep '^a' Ekkor csak olyan "a" fájlnevekre fog illeszkedni a minta, amelyben az "a" betű a fájlnév elején szerepel. Ugyanígy meghatározható illeszkedés a sor végére a "$" karakterrel. ls | grep 'a$' A fenti parancsra olyan fájlnevek illeszkednek, ahol az "a" betű a fájl végén szerepel. Természetesen mindkettő használható egyszerre: ls | grep '^a$' Ekkor olyan fájlnevek illeszkednek, amelyek a-val kezdődnek és vége is van. ===== Többszörözők ===== A többszörözők mindig az előtte lévő karakterre, vagy mintára, vagy zárójeles részre vonatkoznak. Kezdetnek legyen a következő utasításunk: ls | grep a Ez minden olyan állományt listázni fog, amelyben valahol szerepel egy "a" betű. Mint azt fentebb már láttuk, ha ezeket "^" és "$" karakterek közzé tesszük, akkor a fájl neve csak egyetlen "a" betűből állhat (kiterjesztés nélkül). Ha szeretnénk illeszkedést olyan fájlokra, amelynek a neve legalább 1 vagy több "a" betűből áll, akkor használhatunk többszörözőt. Legyen három állomány: touch a touch aa touch aaa Ezek után listázni szeretném őket: ls $ egrep '^a+$' A "+" karakter egy többszöröző. Az előtte lévő "a" karakterre vonatkozik. Azt jelenti, az "a" karakterből egy vagy több lehet, az illeszkedés működik. ^ Többszörözők ^^ ^ többszöröző ^ jelentés ^ | + | egyszer vagy többször | | * | nullaszor vagy többször | | ? | nullaszor vagy egyszer | | {n} | n-szer | | {n,} | legalább n-szer | | {,m} | maximum m-szer | | {n,m} | minimum n-szer, maximum m-szer | ===== Források ===== * https://www.regular-expressions.info/ (2018) * https://hu.wikipedia.org/wiki/Regul%C3%A1ris_kifejez%C3%A9s (2018) * https://intermatrix.hu/regexp (2018)