Magamban előző cikk Alapszinten elmondtam, hogyan működnek a reguláris kifejezések leggyakrabban használt speciális karakterei. Ezekkel a reguláris kifejezésekkel komplex kereséseket lehet végezni szöveges fájlokban vagy más parancsok kimenetében. Ebben a cikkben elmagyarázom, hogyan használhatom a sed parancsot a szöveg megkeresésére és cseréjére sokkal erőteljesebben, mint egyszerűen az egyik szöveget másikra cserélni.
Még egy kicsit a grep parancsról
Mielőtt elkezdeném beszélni a sed-ről, szeretnék még egy kicsit kommentálni a grep parancsot, hogy egy kicsit kiegészítsem az előző cikkben kifejtetteket. Minden, amit mondani fogok, releváns lesz ebben is. Később meglátjuk ennek és a kereséseknek a kapcsolatát.
A reguláris kifejezések egyesítése
Számos speciális karakter, amelyről az előző cikkben beszéltem, nemcsak más karakterekkel, hanem egész reguláris kifejezésekkel is kombinálható. Ennek módja a zárójelek használata egy alkifejezés kialakításához. Lássunk erre egy példát. Kezdjük egy olyan szöveg letöltésével, amelyet tesztelésre használhatunk. Ez a kifejezések listája. Ehhez a következő parancsot fogjuk használni:
curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases
Ezzel a könyvtárban marad, ahol elindít egy fájlt «kifejezések» névvel. Megnyithatja, hogy megnézze és megnevethessen egy kicsit. 🙂
Tegyük fel, hogy meg akarjuk találni azokat a kifejezéseket, amelyek pontosan 6 szót tartalmaznak. A nehézség egy szabályos kifejezés kialakításában van, amely megfelel az egyes szavaknak. A szó nagybetűs vagy kisbetűs betűsor, ami valami hasonló lehet '[a-zA-Z]+'
, de azt is meg kell adnia, hogy ezeket a betűket a betűktől eltérő karakterekkel kell elválasztani, vagyis valami hasonló lenne '[a-zA-Z]+[^a-zA-Z]+'
. Ne feledje: a zárójelben lévő első karakterként a "^" azt jelzi, hogy egyeztetni akarunk olyan karakterekkel, amelyek nem tartoznak a tartományokba, a "+" pedig 1 vagy több karaktert jelöl.
Már van olyan szabályos kifejezésünk, amely megfelel egy szónak. A 6-os párosításhoz 6-szor meg kell ismételni. Ehhez használtuk a kulcsokat, de haszontalan '[a-zA-Z]+[^a-zA-Z]+{6}'
, mert a 6 megismételné a reguláris kifejezés utolsó részét, és mi szeretnénk megismételni az egészet, tehát ezt kell tennünk: '([a-zA-Z]+[^a-zA-Z]+){6}'
. A zárójelekkel részkifejezést képezünk, a zárójelekkel pedig 6-szor megismételjük. Most csak hozzá kell adnia egy "^" -t elöl és egy "$" -t a hátuljához, hogy megfeleljen az egész sornak. A parancs a következő:
grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases
És az eredmény pontosan az, amit szerettünk volna:
Jobban éneklik, mint a Macarena. Jobban kész vagy, mint Luis Aguilé. Kevesebb kultúrád van, mint egy kő. Több nyelvet tud, mint a Cañita Brava. Több ránca van, mint Tutan Khamón. Kevesebben tudsz, mint Rambo, a gyermekgondozásról.
Figyeljük meg, hogy az -E paramétert azért tettük be, mert kiterjesztett reguláris kifejezéseket szeretnénk használni a "+" működéséhez. Ha az alapokat használnánk, meg kellene kerülnünk a zárójeleket és a zárójeleket.
Vissza hivatkozások vagy háttérreferenciák
Ha telepítve van egy helyesírás-ellenőrző, akkor valószínűleg tartalmazni fogja a szavak listáját /usr/share/dict/words
. Ha nem, akkor az arch-ba telepítheti:
sudo pacman -S words
Vagy debianban:
sudo aptitude install dictionaries-common
Ha szeretné, megnézheti a fájlt, hogy megnézze, milyen szavak vannak benne. Valójában ez egy link arra a nyelvre, amelyen a disztribúció található. Egyszerre több szófájl is telepíthető.
Ezt a fájlt fogjuk használni. Kiderült, hogy nagyon kíváncsiak vagyunk mind a hét betűs palindrómára. Azok számára, akik nem tudják: A palindrome capicúa szó, vagyis balról jobbra, valamint jobbról balra is olvasható. Próbálja ki a következő parancsot:
grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words
Kicsit furcsának tűnik, igaz? Ha megpróbáljuk, az eredmény a disztribúció nyelvétől és a listán szereplő szavaktól függ, de az én esetemben a spanyol nyelv esetében ez az eredmény:
anilin anilin gördülő
Nézzük meg, hogyan működik ez a reguláris kifejezés.
A "^" és a "$" mellett, amelyekről már tudjuk, mire szolgál, a bal oldalon először három zárójelbe zárt pontcsoport látható. Ne keverje össze az egyes zárójelek előtti sávok. Meg kell kerülniük a zárójeleket, mert mi használunk reguláris alapvető kifejezéseket, de nincs más jelentésük. A fontos az, hogy bármilyen három karaktert kérünk a pontokkal, de ezek a pontok zárójelbe vannak zárva. Ennek célja, hogy elmentse azokat a karaktereket, amelyek megfelelnek ezeknek a pontoknak, hogy újra hivatkozni lehessen a reguláris kifejezésből. Ez a zárójelek egy másik használata, amely később hasznos lesz a pótlások elkészítésekor.
Itt jön az alábbi három szám, előtte a perjel. Ebben az esetben a sáv fontos. Ez azt jelzi, hogy az alábbi szám háttérreferencia, és az egyik előző zárójelre utal. Például: \ 1 az első zárójelre, \ 2 a másodikra és így tovább.
Más szavakkal, az általunk használt reguláris kifejezéssel azt keressük, hogy mindazok a szavak, amelyek tetszőleges négy betűvel kezdődnek, és amelyeknek a betűje megegyezik a harmadikkal, egy másik pedig megegyezik a másodikkal és egy másik, amely megegyezik az elsővel. Az eredmény a hét betűs palindróma, amelyek szerepelnek a szavak listájában. Ahogy szerettük volna.
Ha kiterjesztett reguláris kifejezéseket használnánk, akkor nem kellene kitérnünk a zárójelek elől, de a kiterjesztett reguláris kifejezésekkel a háttérreferenciák nem minden programban működnek, mert nem szabványosítottak. A grep alkalmazásával azonban működnek, így ez egy másik módja lehet ugyanennek. Kipróbálhatja, ha akarja.
Pótkifejezések: a sed parancs
A keresés mellett a rendszeres kifejezések egyik legjobb felhasználása az összetett szövegek cseréje. Ehhez az egyik módja a sed parancs. A sed parancs ereje messze túlmutat a szöveg helyettesítésén, de itt arra fogom használni. A szintaxis, amelyet ezzel a paranccsal használni fogok, a következő:
sed [-r] 's/REGEX/REPL/g' FICHERO
Vagy:
COMANDO | sed [-r] 's/REGEX/REPL/g'
Ahol a REGEX lesz a kereső reguláris kifejezés, és a CSERÉJET cserélje ki. Ne feledje, hogy ez a parancs valójában nem helyettesít semmit a fájlban, amelyet jelezünk, de amit csinál, az megmutatja a terminál cseréjének eredményét, ezért ne ijedjen meg a következő parancsokkal. Egyikük sem fog módosítani egyetlen fájlt sem a rendszerén.
Kezdjük egy egyszerű példával. Mindannyiunknak vannak különféle konfigurációs fájljai az / etc könyvtárban, amelyekhez általában a "#" kezdetű megjegyzések vannak. Tegyük fel, hogy ezeknek a fájloknak az egyikét megjegyzés nélkül szeretnénk megtekinteni. Például az fstab-tal fogom megtenni. Kipróbálhatja azzal, amelyet szeretne.
sed 's/#.*//g' /etc/fstab
Nem azért fogom ide tenni a parancs eredményét, mert attól függ, hogy mi van az fstab-ban, de ha összehasonlítja a parancs kimenetét a fájl tartalmával, akkor látni fogja, hogy az összes megjegyzés eltűnt.
Ebben a parancsban a keresési kifejezés «#.*
", Ez egy" # ", amelyet tetszőleges számú karakter követ, vagyis a megjegyzések. És a helyettesítő kifejezés, ha megnézi a két sávot egymás után, látni fogja, hogy nincsenek ilyenek, ezért amit csinál, az a megjegyzéseket semmivel helyettesíti, vagyis törli őket. Egyszerűbb lehetetlen.
Most ennek ellenkezőjét fogjuk tenni. Tegyük fel, hogy a fájl összes sorának megjegyzését szeretnénk megtenni. Próbáljuk meg így:
sed 's/^/# /g' /etc/fstab
Látni fogja, hogy a parancs kimenetében az összes sor hash jellel és üres szóval kezdődik. Amit tettünk, a sor elejét lecseréljük a «#
«. Ez is egy meglehetősen egyszerű példa, ahol a cserélendő szöveg mindig ugyanaz, de most még egy kicsit bonyolítani fogjuk.
A helyettesítések kegyelme, hogy a helyettesítő kifejezésben olyan háttérreferenciákat használhat, mint amilyeneket korábban mondtam. Térjünk vissza a kifejezésfájlra, amelyet a cikk elején letöltöttünk. Az összes nagybetűt zárójelbe tesszük, de ezt egy paranccsal tesszük:
sed 's/\([A-Z]\)/(\1)/g' frases
Amit itt találunk, az a visszaváltás a helyettesítő kifejezésben, amely a kereső kifejezés zárójelére utal. A zárójelben lévő zárójel normál zárójel. A helyettesítő kifejezésben nincs különösebb jelentésük, olyanok, amilyenek. Ennek eredményeként az összes nagybetűt ugyanazzal a betűvel helyettesítik, bármi is legyen, körülötte zárójelek.
Van egy másik karakter, amely szintén használható a helyettesítő kifejezésben, ez "&", és helyébe a keresési kifejezés egészíti ki az összes szöveget. Erre példa lehet a fájl összes mondatának idézőjelbe tétele. Ez ezzel a paranccsal érhető el:
sed 's/.*/"&"/g' frases
Ennek a parancsnak a működése nagyon hasonlít az előzőhöz, csak most cseréljük ki a teljes sort ugyanarra a sorra, körülötte idézőjelekkel. Mivel az "&" szót használjuk, nem szükséges zárójelet tenni.
Néhány hasznos parancs reguláris kifejezésekkel
Íme néhány parancs, amelyet hasznosnak vagy kíváncsinak találok, és amelyek rendszeres kifejezéseket használnak. Ezekkel a parancsokkal a reguláris kifejezések hasznossága sokkal jobb, mint az általam eddig bemutatott példáknál, de fontosnak tűnt számomra elmagyarázni valamit a reguláris kifejezések működéséről annak megértése érdekében.
- A man oldal szakaszainak megjelenítése:
man bash | grep '^[A-Z][A-Z ]*$'
Természetesen a bash parancsot bármire megváltoztathatja. És akkor az embertől, közvetlenül a szakaszra léphet, amely érdekel, természetesen egy reguláris kifejezés segítségével. Nyomja meg a «/» gombot a keresés megkezdéséhez és a «^ALIASES$
»Ugrás például az ALIASES szakaszra. Azt hiszem, ez az első alkalmazás, amelyet néhány évvel ezelőtt elkezdtem használni a reguláris kifejezésekben. A kézikönyv egyes oldalain való mozgás szinte lehetetlen ilyen trükk nélkül.
- Mutassa meg a gép összes felhasználójának nevét, beleértve a speciálisakat is:
sed 's/\([^:]*\).*/\1/' /etc/passwd
- Mutassa a felhasználóneveket, de csak azokat, amelyek shell-kel rendelkeznek:
grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'
Valóban egyetlen szabályos kifejezéssel megtehető, de ennek módja túlmutat azon, amit ezekben a cikkekben elmondtam neked, ezért két parancs kombinálásával tettem meg.
- Helyezzen vesszőt a számfájl összes számának utolsó három számjegye elé:
sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers
Csak legfeljebb 6 jegyű számokkal működik, de többször is hívható, hogy elválasztókat helyezzen el a három háromjegyű többi csoportba.
- Az összes e-mail cím kibontása egy fájlból:
grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO
- Válassza szét a fájlban megjelenő összes dátum napját, hónapját és évét:
sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO
- Tudja meg a helyi IP-t:
/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'
Ez egyetlen sed paranccsal is megtehető, de az egyszerűség kedvéért jobb, ha szétválasztom egy grep és egy sed között.
Néhány hasznos cím
Íme néhány cím, amely hasznos lehet a reguláris kifejezésekkel kapcsolatban:
- Reguláris kifejezés könyvtár: Ez egy reguláris kifejezés könyvtár, amelyben az Ön számára érdekes témához kapcsolódó reguláris kifejezéseket kereshet. Webcímek, azonosító vagy bármi más keresése.
- RegExr: Online rendszeres kifejezés-ellenőrző. Ez lehetővé teszi, hogy beírjon egy szöveget, és alkalmazzon rá egy reguláris kifejezést, akár keresésre, akár cserére. Információt ad a reguláris kifejezésről, és van néhány lehetősége annak viselkedésének megváltoztatására.
- Reguláris kifejezések tesztelője: Ez egy kiegészítő a Firefox számára, amely lehetővé teszi a rendszeres kifejezések ellenőrzését a böngészőből.
Következtetés
Egyelőre ennyi. A reguláris kifejezések összetettek, de hasznosak. Időbe telik megtanulni őket, de ha olyan vagy, mint én, a játék velük szórakoztatónak tűnik, és apránként elsajátítja őket. Ez egy egész világ. Sok mondanivaló lenne még, a lusta kvantorokról, a PERL stílusú regexről, a többsorosról stb. És akkor minden programnak meg vannak a jellemzői és a változatai, ezért a legjobb tanács, amit tudok adni, az, hogy mindig nézze meg a program dokumentációját, amelyet használ, valahányszor szabályos kifejezést kell írnia egy új programba.
Hé! …HÉ! … KELJ FEL! … MI MINDENKI ALSZIK? 🙂
Fuentes
Néhány ötlet és példa a cikk reguláris kifejezésére itt vettem át:
- http://sed.sourceforge.net/sed1line.txt
- http://www.thegeekstuff.com/2009/10/unix-sed-tutorial-advanced-sed-substitution-examples/
Mesteri!!!
Nem is olyan rossz, de nagyon köszönöm. Remélem az embereknek tetszik. 🙂
Tetszik ha!
Akkor biztosan jól csináltam valamit. LOL !! 🙂
Nagyon köszönöm a megjegyzést.
Bassza tovább, írja az ember, csak így tovább.
@Blaire Pascal: A hozzád hasonló kommentek ösztönzik. 🙂 nagyon köszönöm !!
Nekem is tetszett ... köszi 🙂
Köszönöm a megjegyzést. Remélem, írok még párat. 🙂
A hozzászólásaid fantasztikusak, sokat tanulsz, inkább elegánsan és hatékonyan hajtod végre a feladatokat.
Gondolt már arra, hogy összegyűjti az összes shell script bejegyzést? A PDF-be rendezve remek kézikönyv lesz.
Sziasztok és köszönöm szépen!
Nagyon köszönöm!! Nem rossz ötlet. Jelenleg csak kettő van, de később gondolok rá. 🙂
nagyon jó cikk, 5+.
Köszönöm. Örülök, hogy tetszik. 🙂
Kiváló! Meg kell változtatnom a következő kifejezést, és nem tudom, hogyan kell csinálni:
192.168.0.138/Szerver 192.168.0.111/adatok szerint
A probléma a "/" szimbólumban rejlik.
A következő parancsot használom:
megtalálja. -name "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
Amit az ilyen típusú feladatok elutasítására használnak, de nem tudom ...
Tudja valaki, hogyan kellene csinálni?
Ölelés!
Seba
Amit meg kell tennie, hogy elkerülje az ilyen karaktert:
megtalálja. -name "* .txt" -exec sed -i 's / \ / Server / \ / data / g' {} \;
Használhat még egy szeparátort a sed-ben. Nem feltétlenül bárnak kell lennie. Sed lehetővé teszi bármely karakter használatát. Például ez egyértelműbb lenne:
megtalálja. -name "* .txt" -exec sed -i 's / Server | / data | g' {} \;
És ha át akarja másolni és beilleszteni a megjegyzés parancsait, legyen óvatos az idézőjelekkel, hogy a wordpress megváltoztatja őket a tipográfiai helyett. 🙂
Üdvözlet.
Kiváló !!!!
Régóta keresem ezt a megoldást.
Itt hagyom a teljes parancsot, amelyet használtam
megtalálja. -name "* .txt" -exec sed -i's | 192 \ .168 \ .0 \ .238 \ / Server | 192 \ .168 \ .0 \ .111 \ / data | g '{} \;
A parancs előnye, hogy rekurzívan megváltoztatja az összes .txt fájlt (vagy a kívánt kiterjesztést) ... Nagyon óvatosnak kell lenned!
De nagyon hasznos !!!
Nos, köszönök mindent és ezer gratulációt az egész csoportnak.
Mindig a levelekből olvastam őket!
Ölelés
Seba