[[: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