Het commando sed is een afkorting voor stream editor. Het is een zeer populair hulpprogramma op Linux/UNIX-systemen. Sed is op zich geen teksteditor. Het kan echter verschillende wijzigingen uitvoeren om een gegeven tekst te manipuleren. De tekstinvoer wordt als een stream verzonden. Sed voert vervolgens de opgedragen acties uit op de stream. Deze gids geeft een overzicht van het sed commando en hoe u het kunt gebruiken om met succes tekst te manipuleren in Linux.
Sed in Linux
De invoerstream van sed kan afkomstig zijn van een tekstbestand of van STDIN (standaardinvoer). We kunnen werken met de uitvoer van een ander commando of rechtstreeks met een tekstbestand werken. De sed tool is vooraf geïnstalleerd op alle Linux distributies.
Sed Usage Overview
Het sed commando heeft de volgende structuur:
|
1 |
$ sed <options> <commands> <file> |
Voor demonstratiedoeleinden hebben we de tekstversie van de GPL license version 3:
|
1 |
$ wget https://www.gnu.org/licenses/gpl-3.0.txt |
Het volgende sed commando zal de inhoud van het tekstbestand afdrukken:
|
1 |
$ sed '' gpl-3.0.txt |
Hier voert sed de bewerkingen uit die binnen de enkele aanhalingstekens zijn beschreven en drukt de uitvoer af. Omdat er geen optie is gedefinieerd, zal sed simpelweg een lege bewerking uitvoeren en de volledige inhoud van het bestand afdrukken.
Sed accepteert ook de uitvoer van een ander commando als invoerstream. Sluis in het volgende voorbeeld de inhoud van het GPL v3-tekstbestand door naar sed om een lege bewerking uit te voeren:
|
1 |
$ cat gpl-3.0.txt | sed '' |
Regels afdrukken
Zonder dat er een optie is opgegeven, zal sed alle inhoud van het bestand rechtstreeks afdrukken. In plaats daarvan kunnen we expliciet het print-commando sturen om de resultaten rechtstreeks naar de standaarduitvoer (STDOUT) af te drukken.
To print the output, use the character p:
|
1 |
$ sed 'p' gpl-3.0.txt |
Standaard drukt sed de uitvoer af op het scherm. Omdat we specifiek het print-commando hebben gebruikt, zal sed elke regel twee keer afdrukken. Sed werkt regel voor regel. Het leest één regel, voert specifieke bewerkingen uit, drukt deze af en gaat naar de volgende regel.
Zoals we kunnen zien, wordt elke regel twee keer afgedrukt. Als het resultaat hierdoor verwarrend is, kunnen we het opschonen met de optie -n. Dit onderdrukt de automatische afdrukfunctie. Omdat we het print-commando sturen, hoeven we de standaardfunctie voor het afdrukken van de uitvoer niet ingeschakeld te hebben:
|
1 |
$ sed -n 'p' gpl-3.0.txt |
Regex-tekenklassen
In reguliere expressies zijn er verschillende tekenklassen. Elk van deze klassen heeft een bereik. Veel klassen hebben ook meerdere expressies. De meeste klassen zijn tekenbereiken:
-
- [a-z]: Lowercase character
-
- [A-Z]: Uppercase character
-
- [0-9]: Digits
-
- [a-zA-z]: Alphabet
-
- [a-zA-z0-9]: Any alpha-numeric character
Deze tekenklassen hebben ook verschillende notaties:
-
- [:lower:]: Lowercase character
-
- [:upper:]: Uppercase character
-
- [:digit:]: Digits
-
- [:alpha:]: Alphabet
-
- [:alphanum:]: Alpha-numeric character
Het volgende commando drukt bijvoorbeeld alle regels af die ten minste één cijfer bevatten:
|
1 |
$ sed -n 's/[[:digit:]]/&/p' gpl-3.0.txt |
Adresbereiken
We kunnen het specifieke deel van de tekststream specificeren om mee te werken. Dit kan de statische locatie van een regel zijn of een bereik van regels. In het eerste voorbeeld drukken we regel 5 af uit het GPL v3-tekstbestand:
|
1 |
$ sed -n '5p' gpl-3.0.txt |
In plaats van een enkele regel kunnen we ook een bereik van regels opgeven om mee te werken. Hier hebben we het adresbereik van regel 5 tot regel 9 (in totaal 5 regels) opgegeven waar sed op zal werken:
|
1 |
$ sed -n '5,9p' gpl-3.0.txt |
Er zijn ook verschillende manieren om het regeladres op te geven. In plaats van zelf de regelnummers te bepalen, kunnen we het vorige voorbeeld zo aanpassen dat sed begint bij regel 5 en op de volgende 5 regels werkt:
|
1 |
$ sed -n '5,+5p' gpl-3.0.txt |
Een andere manier om regels te specificeren is door intervallen te gebruiken. In het volgende voorbeeld begint sed bij regel 1 en werkt op om de andere regel:
|
1 |
$ sed -n '1~2p' gpl-3.0.txt |
Tekst verwijderen
Tot nu toe hebben we gewerkt aan het afdrukken van doeltekstregels. In plaats van afdrukken, kunnen we de regels uit de uitvoer verwijderen. In het volgende voorbeeld verwijderen we meerdere regels vanaf het begin. Hier hoeven we de optie niet te gebruiken -n omdat we willen dat sed al het andere afdrukt dat niet is verwijderd. Voor het verwijderen van regels gebruiken we de optie d:
|
1 |
$ sed '1~2d' gpl-3.0.txt |
Let op dat het bronbestand nog intact is. Sed voert de regelverwijdering alleen uit tijdens de uitvoer. Als je wilt, kun je de sed uitvoer opslaan in een bestand. Je kunt het originele bestand overschrijven of het opslaan als een ander bestand:
|
1 |
$ sed '1~2d' gpl-3.0.txt > gpl-3.0.modified.txt |
In plaats van de uitvoer handmatig naar een bestand te schrijven, kan sed een in-place bewerking uitvoeren op het originele bestand. Kort gezegd zal sed het originele bestand bewerken en eventuele wijzigingen wegschrijven. Deze methode overschrijft het originele bestand, dus wees voorzichtig:
|
1 |
$ sed -i '1~2d' gpl-3.0.txt |
Omdat in-place bewerken gevaarlijk is, sed beschikt over de back-upfunctie. Gebruik bij het uitvoeren van in-place bewerkingen -i.bak in plaats van -i om een back-up te maken voor het bewerken. Sed zal het back-upbestand maken met de .bak-extensie:
|
1 |
$ sed -i.bak '1~2d' gpl-3.0.txt |
Tekstvervanging
Dit is veruit een van de meest voorkomende toepassingen van sed. Het zoekt naar een tekstpatroon en vervangt dit patroon door een opgegeven tekst. Hier wordt het tekstpatroon beschreven in reguliere expressies (kortweg regex). Volg deze handleiding voor meer informatie over het gebruik van regex, waarin wordt uitgelegd hoe je Grep met regex gebruikt om te zoeken naar tekstpatronen in bestanden.
Hier is een voorbeeld van de meest elementaire tekstvervanging met behulp van regex:
|
1 |
$ 's/<search_pattern>/<replacement>' |
Hier is s het commando voor vervanging. De slashes zijn scheidingstekens voor het patroon en de vervanging. Laten we het in de praktijk brengen:
|
1 |
$ echo "hello world" | sed 's/hello/HELLO/' |
Het volgende voorbeeld demonstreert het gebruik van de underscore (_). Hier fungeren de underscores als scheidingstekens:
|
1 |
$ echo http://example.com/index.html | sed 's_com/index_net/home_' |
Hier zoeken we naar com/index om te vervangen door net/home. Let op de plaatsing van de underscores, want die is cruciaal. Als je bijvoorbeeld de laatste underscore mist, zal sed een foutmelding geven:
|
1 |
$ echo "http://www.example.com/index.html" | sed 's_com/index_net/home' |
We hebben een dummybestand nodig om wat vervangingen te oefenen. Hier heb ik een ingekorte versie van het GPL v3-tekstbestand:
|
1 |
$ cat gpl-3.0.cropped.txt |
Laten we een paar basis-tekstvervangingen uitvoeren:
|
1 |
$ cat gpl-3.0.cropped.txt | sed 's/GNU/GNU is Not Unix/' |
Kijk eens naar het volgende voorbeeld. We willen alle instanties van the veranderen in THE :
|
1 |
$ echo "the the quick brown fox jumps over the lazy dog" | sed 's/the/THE/' |
Valt je iets op? Sed heeft niet alle instanties van the. gewijzigd. In feite is alleen de eerste instantie gewijzigd. Wat is er aan de hand? Dit is het standaardgedrag van de optie s. Het matcht alleen de eerste instantie van een bepaalde regel en gaat dan door naar de volgende. Om ervoor te zorgen dat sed de hele regel controleert op het zoekpatroon, moeten we een optionele vlag gebruiken: g. Laten we het commando corrigeren:
|
1 |
$ echo "the the quick brown fox jumps over the lazy dog" | sed 's/the/THE/g' |
Nu werkt het zoals bedoeld. Een andere interessante manier om het commando te gebruiken is door het aantal te wijzigen instanties op te geven. In het vorige voorbeeld waren er 3 instanties van the, toch? Wat als we opgeven om alleen de 3e instantie te wijzigen? De wijziging vindt plaats bij de optionele vlag:
|
1 |
$ echo "de de snelle bruine vos springt over de luie hond" | sed 's/the/THE/3' |
Als je met een groot tekstbestand werkt, kan het helpen als sed alleen die regels afdrukt waarin de vervangingen hebben plaatsgevonden. Om dat te bereiken, moeten we nog een extra vlag toevoegen p:
|
1 |
$ sed -n 's/GNU/GNU is Not Unix/gp' gpl-3.0.txt |
Hoofdlettergevoeligheid
By default, all the sed -bewerkingen zijn hoofdlettergevoelig. De volgende opdracht demonstreert het standaardgedrag van hoofdlettergevoeligheid:
|
1 |
$ echo "HELLO WORLD" | sed 's/hello/hElLo/' |
Vanwege het verschil in hoofdletters is er geen verandering. In zo'n situatie kunnen we sed vragen om hoofdlettergevoeligheid uit te schakelen. Voeg hiervoor de optionele vlag toe i:
|
1 |
$ echo "HELLO WORLD" | sed 's/hello/hElLo/i' |
Teksten vervangen en hiernaar verwijzen
De kracht van sed ligt voornamelijk in het vermogen om reguliere expressies te gebruiken. Met geavanceerdere en complexere regex-patronen kunnen we veel meer bereiken. We kunnen bijvoorbeeld tekst vanaf het begin van een bestand tot een bepaalde locatie vervangen. Bekijk de volgende expressie:
|
1 |
$ sed 's/^.*GNU/GNU_replaced/' gpl-3.0.txt |
Hier geeft het caret-teken (^) de start van de regel aan. De 'match-any-character'-operator wordt aangeduid met een punt (.). Het sterretje (*) is de wildcard-expressie, die matcht vanaf het begin van de regel tot aan GNU.
Een andere interessante truc is het gebruik van het &-symbool. We kunnen dit gebruiken om de gebieden te markeren die sed vindt met het zoekpatroon:
|
1 |
$ sed 's/^.*GNU/(&)/' gpl-3.0.txt |
Tot slot
In deze handleiding hebben we de basisbeginselen van de sed -opdracht verkend. We hebben geleerd hoe we specifieke regels kunnen afdrukken, in teksten kunnen zoeken, teksten kunnen verwijderen en vervangen, teksten kunnen overschrijven en reguliere expressies kunnen gebruiken. Een correct opgebouwde sed-opdracht kan een tekstdocument drastisch transformeren. Je kunt nu met succes tekst manipuleren in Linux met behulp van sed.
Veel computerplezier!









Reacties
Nog geen reacties. Wees de eerste.