Tartalomjegyzék
Sed
- Szerző: Sallai András
- Copyright © 2011, Sallai András
- Szerkesztve: 2011, 2012, 2013, 2016, 2022
- Licenc: CC BY-SA 4.0
- Web: https://szit.hu
Bevezetés
A sed egy nem-interaktív szövegszerkesztő. Az alapértelmezett bemenet szerkesztjük, ezért helyesebb így nevezni: áradatszerkesztő. Tulajdonképpen egy állomány sorait szerkesztjük.
A sed az első UNIX rendszeren jelent meg, mint használható parancs.
Egy rövid gyorstalpalót találunk itt mintákkal.
Jellemzők
- Nem olvassa pufferba a fájlokat, ezrét nagyon nagy fájl esetén is használható.
- Kimenete standard output.
- Képes reguláris kifejezések értelmezésére.
- A parancsok jöhetnek:
- parancssorból
- fájlból
Munkaállomány
A példa kedvéért legyen egy szöveges állomány, amit használunk a leírásban:
- piroszrt.txt
No. Név Lakhely Fizetés Telephely 001 Nagy József Szolnok 380000 Szolnok 002 Sörös Tamás Miskolc 257000 Mezőkövesd 003 Tas Ferenc Szolnok 321500 Szolnok 004 Pék Lajos Szeged 289000 Szeged 005 Ábel Géza Szeged 349000 Makó 006 Üres Tibor Miskolc 341000 Miskolc 007 Teli Gábor Szolnok 289000 Cegléd 008 Erszény Ferenc Miskolc 372000 Miskolc 009 Fűrész Tibor Szeged 280000 Szeged 010 Szegi Lajos Szeged 389000 Szeged 011 Pető Lajos Szeged 301000 Szeged 012 Fűrész Tibor Miskolc 500400 Mezőkövesd
Csere
A legáltalánosabb feladat, amikor egy szövegrészt ki kell cserélnünk egy másikra.
Csereszintaxis
[cím]s/minta/helyettesítő/jelzők
Jelzők
- n – egy szám 1- 512 között, hányadik egyezést cseréljük
- g jelző - a sorban minden egyezést cserélünk
- p jelző - az egyező sorokat kiírja
- w jelző - a wfilenev - A tartalmat fájlba írjuk
Szócsere
Adott a piroszrt.txt állomány amelyben dolgozók adatait tartalmazzák. A fájlban a Tamás nevet Tomra kell cserélnünk, az eredményt pedig a dolgozok01.txt fájlban szeretnénk viszontlátni.
sed s/Tamás/Tom/ piroszrt.txt > dolgozok01.txt
Mondatok cseréje
Ebben a példában már egy teljes nevet cserélünk. Nekünk abból szempontból érdekes a teljes név, hogy tartalmaz egy szóközt is.
sed s/"Sörös Tamás"/"Sörös Tom"/ piroszrt.txt > dolgozok02.txt
Szóközök esetén tegyük a karaktersorozatot idézőjelek közzé.
Megoldást jelent az is ha az egész szerkesztő parancsot teszem idézőjelek közzé.
sed "s/Sörös Tamás/Sörös Tom/" piroszrt.txt > dolgozok02.txt
Illesztés adott sorokra
Előfordulhat, hogy egy Fűrész nevet kell kicserélnünk, de a név több sorban is szerepel, nekünk pedig csak az 012 azonosítójúnál kell cserélni. Ekkor keresnünk kell a cserélendő sorban valami azonosítót, amely a Fűrész vezetéknevű embert egyértelműen azonosítja. A példánkban a 012-es nekünk megfelel. A sed parancsnak ezt is megadhatjuk:
sed /012/s/Fűrész/Feszes/ piroszrt.txt > dolgozok03.txt
Ha a fenti szintaxismintát nézzük akkor a címet adtuk meg, ami nem kötelező elem.
Illesztés a sor elejére
Az előbbi megoldás szépen működik. De nehézségekbe ütközünk például 010 azonosítójú dolgozó (Szegi Lajos) Települését szeretnénk megváltoztatni. A gondot nem az okozza, hogy amit változtatni kell az a Település oszlopban van. A gond a Fizetés oszlopban van. Ha megfigyeljük 011 (Pető Lajos) fizetését szerepel benne a „010” karaktersorozat. Így amikor az előbbi módon akarjuk megváltoztatni a 010 dolgozó települését, a 012 települése is megváltozik.
Jeleznünk kell, hogy csak azt a „010” karaktersorozatot fogadom el illeszkedésnek, amely a sor elején van. Ezt a „^” karakterrel lehetséges:
sed /^010/s/Szeged/Makó/ piroszrt.txt > dolgozok04.txt
Illesztés a sor minden tagjára
Jelen feladatunkban a 010 dolgozónak nem csak a települése, de a telephelye is megváltozott. Az előbb megoldást viszont csak az első előfordulást változtatta meg. Ezen segít a sed parancs végre tett „g” zászló:
sed /^010/s/Szeged/Makó/g piroszrt.txt > dolgozok04.txt
Illesztés a sor második tagjára
Megint problémánk lehet, ha csak a telephelyet kell Makóra változtatni. A fenti megoldásaink ekkor nem működnek. A „g” jelző helyett, azonban megadhatunk egy számot is, amely az adott sorban csak azt a számú illeszkedést változtatja, amelyet megadtunk:
sed /^010/s/Szeged/Makó/2 piroszrt.txt > dolgozok04.txt
Az adott sorban csak a második Szegedet változtatja Makóra.
Beszúrás
Meg kell adnunk milyen sor elé szúrunk be: Például:
sed '/exit 0/i sajatScript.sh' rc.local
Csere sorszám alapján
Második sorban cserélünk:
sed '2 c ez a szöveg fájlnév
Változások fájlba írása
A következő példában az összes Szegedi települést Hatvanra változtatom, majd a csak a megváltoztatott sorokat a hatvan.txt fájlba írjuk:
sed s/Szeged/Hatvan/whatvan.txt dolgozok.txt
Ez a szerkesztő parancs végére írt „w” karakterrel érem el, amely után azonnal whitespace karakterek nélkül a kimeneti fájl nevét is leírtam.
Eredeti szerkesztése
Az eddigi példák nagyrészében az eredmény csak az alapértelmezett kimenetre ment, persze irányíthattuk fájlba is. Lehetőség van azonban az eredeti fájl szerkesztésére -i kapcsoló segítségével:
sed -i /002/s/Sörös/Seres/ piroszrt.txt
Ekkor a piroszrt.txt fájlt szerkesztjük.
Törlés
Ha egy szövegrészt szeretnénk törölni, az megoldható az előző csere segítségével, hiszen annyit kell tennünk, hogy a cserélendő szöveg üres lesz. Most egy olyan lehetőséget nézünk meg, amely kifejezetten egy sor törlésére ad lehetőséget.
sed /009/d piroszrt.txt
Szerkesztés
-e kapcsoló
Az (e) az angol edit szóból van, amely szerkesztést jelent.
Azt jelezzük, hogy a szerkesztőparancsok a sed parancssorában találhatók
Egyetlen parancs esetén elhagyható, mint azt fentebb így is tettük!
Szigorúan véve:
sed -e /065/d piroszrt.txt
Kettős parancs
sed -e /^064/d -e s/Tamás/Tom/ piroszrt.txt > dolgozok.txt
Parancsok állományban
A parancsok állományba tétele
A használandó sed parancsokat állományba is tehetjük. Amikor szeretnénk azokat felhasználni egyszerűen megadjuk a parancsfájl elérését.
Parancsállomány létrehozása
cat > cmds /^056/s/Sörös/Seres/ /^055/d ^D
A parancsállomány alkalmazása
sed -f cmds fájl > file2
Adott sorok kiíratása
A grephez hasonló működés
sed -n /Sörös/p piroszrt.txt
Könyvtárkezelés
A célunk, hogy egy könyvtárban lévő összes állományon végrehajtsunk egy parancsot:
ls | sed ”s/^/ parancs /” | sh
A tr-hez hasonló működés
sed y/áéí/aei/ dolgozok.txt
Leállás adott sornál
sed 4q dolgozok5.txt
Leállás adott mintánál
sed /Sörös/q dolgozok5.txt
Egy sorban több csere
A sed parancs minden sorban cserél, de csak az első előfordulásnál.
sed s/ : /" "/ dol5 > dol7
sed s/ : /" "/g dol5 > dol7
A g arra utasít, hogy minden előfordulásnál cseréljünk
Tabulátorral tagolás:
sed s/ : /"\t"/g dol5 > dol7
A p jelző használata
sed -n '/xzy/p' filename
Többszörös szóközök eltávolítása
sed 's/ */ /' < adat.txt
Az (*) karakter előtt két szóköz van. A (*/) után egy szóköz van.
DOS2Unix sortörés
A DOS sortörések átalakítása Unix sortöréssé.
sed -i 's/\r//' fajlnev.txt
A -i kapcsoló hatására nem a szabványos kimenetre ír, hanem a fájlban hajtja végre a változtatást.
Esetleg:
sed -i s/"\r"// fajlnev.txt
A sed elválasztó helyettesei
Ha leírok a mintaillesztéshez egy sort, az elválasztónak a „/” karaktert használtuk eddig.
Például:
sed s/Tamás/Tom/ piroszrt.txt > dolgozok01.txt
Ha feldolgozandó szöveg elve tartalmaz „/” karaktereket, akkor escape szekvenciákkal kell megoldanunk a feladatot.
Legyen a következő állomány:
- users.txt
Tulajdonos:Könyvtár janos:/home/fejlesztes/janos joska:/home/fejlesztes/joska mari:/home/gazdasag/mari kati:/home/human/kati teri:/home/human/teri
Tegyük fel, hogy a kati felhasználó könyvtárát ki kell cserélni human-ról gazdasag szóra. Ekkor a következőt írhatom:
sed 's@kati:/home/human@kati:/home/gazdasagi@' users.txt
A „/” karakterek helyett „@” karaktert használtam.
Szeparátorként a „/” karakter helyett a következők használhatók:
@ % | ; :
Függelék
fstab szerkesztése
Tegyük fel, hogy az /etc/fstab állományban egyik merevlemez azonosítója /dev/sdb1 néven van megadva. Az sdb1 eszköz van csatolva a /home csatolási pontra. Szeretnénk lecserélni UUID azonosítóra. Az UUID azonosítót megmutatja a lsblk -f parancs. Ennek kimenetét a grep és a colrm paranccsal szűrjük, így megkapjuk az UUID azonosítót. Ez az értéket beírnunk a /dev/sdb1 helyére. Megoldás:
sed -ire 's/\/dev\/sr0/`lsblk -f | grep \/home | colrm 1 22 | colrm 37`/g;s/.*/echo &/;e' /etc/fstab
Használat előtt ellenőrizzük, hogy az lsblk a szűrésekkel együtt a megfelelő UUID értéket adja.
lsblk -f | grep \/home | colrm 1 22 | colrm 37