Sed – a Linuxos szövegcserélő

Linux kezdő
Linux kezdő

Sed, a szövegmanipulátor. Ez a program egy nagyon jó, és összetett program, hasonlóan a grep-hez. Most sem célom a haladóknak összeállítani egy kézikönyvet, csak annyi a cél: aki Linuxban kezdő, tudjon róla. Ha majd kell, akkor elő tudja venni, kicsit olvasni a leírásokban és haszonnal forgatni. Aki már az rnm, grep, regex cikkeket olvasta, annak nem lesz újdonság: ez egy parancssori megoldás és nagyon sok helyen hasznos lehet. Bár nem teljes az átfedés, de aki az rnm-et használja regexekkel, annak a megszerzett tudás itt is hasznos lesz. Itt is jól használhatóak a szabályos kifejezések. Az elején menjünk gyorsan végig azokon, amiket a grep-nél már leírtam.

Igen, a feladatok nagy része amire a sed ki lett találva egy-egy grafikus szövegszerkesztőben is megoldható: sima csere, vagy mindet cserélje funkció ott van a legtöbben. Így aki nem szereti a Linux parancssort, annak nem kötelező a sed-et használni. Itt is a három fő indok a sed mellett:

  • Parancssorból elérhető, gyors megoldás, ha kezelni tudod. Ha csak grafikus felületen dolgozol, akkor nem feltétlen lesz erre szükséged.
  • Tömegmunkára alkalmas ez a megoldás. Ha egy műveletet (pld. csere) szeretnél véghezvinni nagyon sok fájlon, akkor ezzel simán megteheted. Ez sem egy mindennapi feladat, de pár alkalommal jól jöhet.
  • Scriptben, vagy csővezetékben (egymásután összekapcsolt parancsok, ahol az egyik kimenetét dolgozza fel a következő automatikusan) igencsak jól használható. Ez a fő terület, amiért érdemes átgondolni az alapok elsajátítását. “Röptében” dolgozod fel az adatokat, és csak az eredményt kapod meg.

A sed nagyon leegyszerűsítve egy szöveg manipuláló, jellemzően karakterek cseréjére, vagy beszúrására, törlésére használt program. Nagy előnye az összetett, skálázott műveletek értelmezése. Ami egy nagyon nagy hátrány is! Ha egy kezdő meglátja a sed leírást rögvest elmegy a kedve az egésztől: na ne… ezt nem lehet megtanulni, és minek is, ha van grafikus megoldás! Az elején próbáljuk meg az alapokat használni, a sima cseréld le ezt a szöveget erre funkciót. Majd haladjunk lépésről, lépésre.

sed 's/ezt/erre/' ebbenafájlban > eredmény

A parancs felépítés ismert a rnm-ből, így nagy meglepetést nem fog okozni az eredmény.

Sed és a csere – ami a legfontosabb

Igen, ez az adott bemeneti fájlt manipulálja, mert ez a feladata. Ha ez az alap, akkor minek emlegetni? Mert felülírjHATJA az eredetit, ami ha valamit elrontottál komoly károkat is okozhat. Főleg, mert sok esetben konfigurációs fájlokat is manipulálhatunk. Így érdemes egy másolaton dolgozni, tesztelni, főleg, ha nem egy sima „cseréld le ezt a szót erre a szóra” műveletet használod!
Illetve érdemes ezt a kapcsolót is megismerni

-i[UTÓTAG], –in-place[=UTÓTAG] fájlok szerkesztése helyben (biztonsági mentést készít, ha
az UTÓTAG meg van adva)

Ahogy eddig is, egy sed -h nagyon jól kilistázza a lehetőségeket. Így egy már a grep-ből ismert feladat, a komment sorok kiszedése esetén használt parancsnál

sed -i.bak -r '/^#/d' ./Cozy > ./Cozy2

a -i.bak készít egy másolatot a Cozy szövegfájlról és azután szedi ki az # sorokat. Így a Cozy2-ben lesz az eredmény, de ha valami mégsem lett volna jó, akkor a Cozy.bak-hoz visszatérhetünk. Igencsak érdemes megjegyezni ezt, és ha kell használni. Itt az -r a törlési parancs.
Erre normál, odafigyeléssel használva kicsi az esély, de jobb az óvatosság.

Így már az üres sorok törése sem lesz gond egy szövegfájlban.

Ok, ennyi figyelmeztetés után hozzunk létre egy szövegfájlt, alma.txt néven.

Az alma finom. Az alma jó. Az alma gyümölcs.
Az alma a kedvencem.
Az alma az alma és nem körte!
alma, alma, alma
Alma, alma, alma

Mivel ez nem egy hosszú szöveg az eredményeket a terminálra küldjük, azaz nem adunk meg célfájlt.

sed 's/alma/körte/' alma.txt

Ez a leggyakrabban használt csere megoldás: egy szót egy másikra. OK, mi a kimenet?

Az körte finom. Az alma jó. Az alma gyümölcs.
Az körte a kedvencem.
Az körte az alma és nem körte!
körte, alma, alma
Alma, körte, alma

Hm… nem teljesen az, amit akartunk. Így egyszerűen megadva csak a sor első találatát cseréli ki. Sor és első – ez a két kulcsszó!

Összes találatot cserélve ki:

sed 's/alma/körte/g' alma.txt

Ne másold ezt automatikusan be, hanem ha az előbb megtetted, hogy kipróbáltad, akkor egy felfele nyíl és akkor az utolsó parancsot megkapod és szerkeszteni tudod.

Az körte finom. Az körte jó. Az körte gyümölcs.
Az körte a kedvencem.
Az körte az körte és nem körte!
körte, körte, körte
Alma, körte, körte

Na minden alma körte lett! A g adja, hogy az összest cserélje végig a sorban. A kulcsszó a végig és a sorban!

Csak minden második találatot cserélje ki a sorban:

sed 's/alma/körte/2' alma.txt

Az alma finom. Az körte jó. Az alma gyümölcs.
Az alma a kedvencem.
Az alma az körte és nem körte!
alma, körte, alma
Alma, alma, körte

A második után mindet cserélje le:

sed 's/alma/körte/2g' alma.txt

Az alma finom. Az körte jó. Az körte gyümölcs.
Az alma a kedvencem.
Az alma az körte és nem körte!
alma, körte, körte
Alma, alma, körte

Bár jellemzően a g kapcsolót használjuk, de ezeket “a sorban n-dik találatokat” is ismerni kell, ha pld. egy csv azaz szöveges táblázatot kell manipulálni.

Alapesetben minden sort feldolgoz a sed. De van lehetőség arra is, hogy egy adott sort kiválasztunk:

sed '2 s/alma/körte/g' alma.txt

Az alma finom. Az alma jó. Az alma gyümölcs.
Az körte a kedvencem.
Az alma az alma és nem körte!
alma, alma, alma
Alma, alma, alma

De nyilván egy tól-ig sor tartományt is megadhatunk

sed '2,4 s/alma/körte/g' alma.txt

Az alma finom. Az alma jó. Az alma gyümölcs.
Az körte a kedvencem.
Az körte az körte és nem körte!
körte, körte, körte
Alma, alma, alma

A sed ‘2,$ s/alma/körte/g’ alma.txt egyértelmű, ha nem próbáld ki…

Az elején láttuk, hogy nem mindegyik alma lett körte a /g kapcsolóval, az Alma nem. Így már látjuk, hogy a sed a pontosság híve. Ha kis és nagybetűt egyben akarod kezelni, akkor /I a megfelelő:

sed 's/alma/körte/gI' alma.txt

Az körte finom. Az körte jó. Az körte gyümölcs.
Az körte a kedvencem.
Az körte az körte és nem körte!
körte, körte, körte
körte, körte, körte

A sed sortörlésre is alkalmas:

sed '2d' alma.txt

Az alma finom. Az alma jó. Az alma gyümölcs.
Az alma az alma és nem körte!
alma, alma, alma
Alma, alma, alma

A sed ‘$d’ már nem okozhat gondot, sem a sed ‘3,6d’ sem a sed ’12,$d’ hiszen az ilyen megoldásokról volt szó.

Egy adott mintát tartalmazó sor törése:

sed '/jó/d' alma.txt

Az alma a kedvencem.
Az alma az alma és nem körte!
alma, alma, alma
Alma, alma, alma

A sort törli, nem a mintát!

Az adott minta törlése:

sed 's/alma//gI' alma.txt

Az finom. Az jó. Az gyümölcs.
Az a kedvencem.
Az az és nem körte!
, ,
, ,

Gondold át, hogy bár alma a törlendő, de az Alma is eltűnt. Miért?
Most nézzük meg, hogy mi van az alma.txt-ben. Az eredeti szöveg. Azaz az nem változott meg, csak beolvasta a sed! Így az elején elhangzott figyelmeztetés kicsit túlzónak tűnik, de sokszor így használjuk, ha egy fájlba akarunk valamit átíratni:

sed 's/alma/körte/gI' alma.txt > alma.txt

Miért? Mert véglegesíteni akarjuk a változást, és nem egy új fájlt létrehozni. Ha pedig ez egy config fájl és komplexebb változtatás hajtunk végre, akkor az már fájóbb, ha eltoljuk, és nincs másolatunk! Én kerülném az ilyen megoldást, az elején előbb egy másik fájlba küldjük át az eredményt, majd ha az 100%-ig jó, csak akkor írasd felül az eredetit!

Nagyon kellemes a dupla szóköz törlésére…

Készítsünk egy ilyen fájlt:

baka, boka, bika, baka, boka, bika

Legyen a neve boka.txt.

sed 's/ /x/g' boka.txt

A láthatóság kedvéért x-re cseréltetem a dupla szóközöket.

baka, boka,xbika,x baka,x boka,xxbika

Ok, ez nem jó, hiszen a duplákat lecserélte egyre, de ha több van, 3 vagy több akkor kellene valami sokszorozó, hogy megmondja neki, hogy egynél többet cseréljen le…

Dupla szóköz, de ha tripla, vagy több? Azaz le kellene cserélni az összes, egynél több szóközt egyre.
Gond egy szál sem, hiszen ez kezeli a regex-eket és ott már tudjuk, hogy a + jel azt mondja meg, hogy egy, vagy több abból ami előtte van.

sed 's/ +/x/g' boka.txt

baka, boka, bika, baka, boka, bika

Ne már! Ez gyagya, ott a szóköz és a + is, hogy egy vagy több? Mit nem ért ezen? Itt jön a legnagyobb kavarás, probléma és szívatás, amit ki lehetett találni. A sed itt mit lát? Egy space és egy + jel. Na ezt akarja megkeresni és nem regex-ként nézi a + jelet. Így meg kell majd neki magyarázni, hogy a + jel az nem egy sima plusz jel, amit keresni kell, hanem valami különleges karakter. Ezt a módszert már ismerjük, egy „visszaper” azaz \ jel kell a különleges karakterek elé. Így a helyes megoldás:

sed 's/ \+/x/g' boka.txt

Ha ezt lefuttatod, akkor már a helyes, egy x van az ott, ahol kell felállást kaptad.

baka,xboka,xbika,xbaka,xboka,xbika

Ok, mi ebben a szívatás? Semmi, ha haladó vagy, és van egy kis rutinod. Ha kezdő vagy, akkor a fenti példában látott megoldást általánosnak gondolod: ha különleges a karakter, akkor tegyünk elé egy visszaper jelet, és akkor regex-ként értelmezi a rendszer. De sajnos nem ilyen egyszerű a helyzet. Nem minden program értelmezi ilyen módszerrel a dolgokat. Van amelyik pont fordítva: ha lát egy különlegesnek gondot karaktert, akkor annak is értelmezi. Ilyeneknél pont fordítva van, ha a különlegesnek gondolt karaktereket szó szerint akarjuk értelmeztetni, akkor azok elé kell a visszaper, hogy az adott program szó szerint vegye a karaktert. Nagyon jó példát a torrent letöltéses cikkben találsz. Bár ott egy szeparációval, dupla idézőjellel oldottuk meg a letöltési link „egyben értelmezd, és ne törődj a különleges karakterekkel” problémát.
Így ha valami nem úgy működik, ahogy szerinted kellene, akkor erre is gondolj!

Ok, lépjünk tovább, és cseréljük ki a baka, boka szót bikára.

A megoldást már ismerjük. Az

sed 's/[oa]k/ik/g' boka.txt

Legtöbb esetben működik. A példa nem hiába került ide, bár nem túl érdekes. Látható, hogy itt nem kellett nálam a \ jel a különleges [] karakterek elé berakni.

Bár itt jellemzően a terminálra írattuk ki az eredményt, de értelemszerűen a cél lehet egy fájl is. A fenti példában ez

sed 's/[oa]k/ik/g' boka.txt > ide.txt

lenne. Így nem a terminálban, hanem a fájlban kell keresni a kész művet.

Én ennyit gondoltam alapnak. Ha nem ment el a kedved tőle, akkor már tudod, hogy van ilyen és ha kell, akkor a konkrét feladatra használni is tudod majd. Nem egyszerű, de pár próbálkozás után már igencsak kezes jószág lesz. Az a szerencsénk, hogy ez egy általánosan kedvelt eszköz Linux alatt, így ok leírás, és példa található az interneten.

Related Posts