[[:oktatas:linux|< Linux]]
====== Sed ======
* **Szerző:** Sallai András
* Copyright (c) 2011, Sallai András
* Szerkesztve: 2011, 2012, 2013, 2016, 2022
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|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:
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:
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
===== Irodalom =====
* https://www.gnu.org/software/sed/manual/sed.html