SED

UNIX Stream EDitor

Introductie

sed of volluit stream editor is een niet-interactieve editor. Het interpreteert een script en voert de bewerkingen in dat script uit.

sed is een stream-gebaseerd programma, omdat net zoals bij veel *NIX1 programma's de invoer door het programma loopt en er via de standard output weer uit komt. Dit in tegenstelling tot vi.

De invoer voor sed komt meestal van een bestand, of via een pipe (hoewel het ook via het toetsenbord kan).

De uitvoer gaat standaard naar de standard output (het beeldscherm), maar kan ook weer via een pip doorgestuurd worden.

sed wordt meestal gebruikt voor
  1. Een of meerdere bestanden automatisch to bewerken
  2. Het herhaaldelijk bewerken van meerdere bestanden gemakkelijker maken
  3. Het schrijven van converteer programma's

Werking

sed werkt als volgt
  • Iedere invoer regel wordt opgeslagen in een special geheugen-buffer of pattern space
  • Alle bewerkings-commando's in een sed script worden in volgorde uitgevoerd op alle invoer regels.
  • Bewerkings-commando's worden toegevoegd op alle regels (globaal), tenzij dit beperkt wordt voor bepaalde regels met line addressing
  • Als een commando de invoer aanpast, worden volgende commando's en adres controles toegepast worden op de huidige regel in de buffer (pattern space) en niet de originele invoer regel.
  • Het originele bestand wordt niet aangepast, omdat de bewerkingen gebeuren op een kopie van de invoer-regel. Deze kopie wordt naar standard output gestuurd en kan verder doorgestuurd worden naar een bestand.
  • sed gebruikt ook een speciale buffer (hold space) waarin gegevens opgeslagen kunnen worden, om deze later terug te halen.

Commandoregel Syntaxis

Wij zijn natuurlijk vooral geïnteresseerd in de toepassing van sed op de commandoregel.

De syntaxis voor het gebruik van sed is als volgt

sed [-n] [-e] 'commando' bestand(en)

of

sed [-n] -f scriptbestand bestand(en)

De eerste vorm voert het ingegeven commando uit op de gekozen bestanden, een commando wordt omsloten door enkelvoudige aanhalingstekens ('). De tweede methode maakt gebruikt van een scriptbestand (dat sed-commando's bevat). Beide vormen mogen samen gebruikt worden, en meerdere keren.

Als er geen bestand wordt aangegeven zal sed de invoer van standard input gebruiken (meestal het toetsenbord).

sed kent de volgende parameters
  • -n Onderdruk de standaard uitvoer; sed zal enkel regels tonen die gespecificeerd zijn met het p commando, of met de p "flag" van de s parameter
  • -e cmd Het volgende argument/parameter is een editor commando, dit is handig als je meerdere scripts of commando's na elkaar gebruikt
  • -f Het volgende argument/parameter is een bestand dat bewerkings-commando's bevat.
Opmerking: Als bij een script bestand de eerste regel #n bevat, zal sed zich gedragen alsof de -n parameter is meegegeven. LET OP! als je -n gebruikt op een bestand zonder de p flag te gebruiken zal sed geen uitvoer geven!

SED Syntaxis

een sed commando ziet er als volgt uit:

[adres[,adres]][!]commando [argumenten]

sed kopiëert iedere regel van de invoer in de pattern space. De instructies die we aan sed geven bestaan uit "adressen" en "bewerkings-commando's". Als sed een match vindt met een adres zal het commando uitgevoerd worden op de kopie in de pattern space.

Indien een commando geen adres heeft, zal sed het commando toepassen op alle regels van de invoer.

Als een commando de inhoud van de pattern space aanpast, worden de volgende commando's toegepast op die aangepaste regel in de pattern space en niet op de originele invoer.

Commando's

Een sed commando kan nul, een of twee adressen aangeven. Een adres kan een regel-nummer zijn, het symbool voor de laatste regel ($) of een regular expression omsloten in slashes (/patroon/). Ook kan \n gebruikt worden om "iedere nieuwe regel" aan te geven, maar niet het newline teken aan het einde van de pattern space.
Tabel 1. adressen
Het commando specificeert Het commando wordt toegepast op
Geen adres Iedere invoer-regel
Een adres Iedere regel die overeenkomt met het adres. Bepaalde commando's aanvaarden maar een adres (a, i, r, q en =
Twee adressen (door comma's gescheiden) De eerste overeenkomende regel en alle regels daarna tot en met de regel die overeenkomt met get tweede adres
Een adres gevolgd door ! Alle regels die niet overeenkomen met het adres
Voorbeelden
Tabel 2. Commando voorbeelden
Commando Uitgevoede actie
s/xx/yy/g Vervang op alle regels (xx door yy)
/BSD/d Wis de regels die BSD bevatten
/^BEGIN/,/END/p Print van BEGIN tot en met END.
/SAVE/!d wis iedere regel die geen SAVE bevat
/BEGIN/,/END/!s/xx/yy/g Vervang op alle regels behalve tussen BEGIN en END

Commandoregel voorbeeld

$ sed -e 's/xx/yy/g' tekstbestand.txt

sed maakt gebruik van haakjes ({ }) om adressen in elkaar te "nesten" of om meerdere commando's aan hetzelfde adres te koppelen.

Voorbeeld
[/patroon/[,/patroon/]]{
commando1
commando2
}

Het "open" haakje moet het laatste teken op de regel zijn! en het sluithaakje moet op zijn eigen regel staan.

Alfabetische lijst van sed commando's

Tabel 3. sed commandos
sed commando Omschrijving
# #

Begin een opmerking in een sed script (enkel geldig als het eerste teken op de eerste regel)2, als de eerste regel van het script #n is zal sed zich gedragen alsof -n is gegeven als parameter

: : label

Geef een regel een label om de controle hiervan door te geven aan b of t, en label mag uit maximaal 7 tekens bestaan

= [/patroon/]=

Schrijf het regel nummer van iedere tegel die overeenkomt met het patroon naar standard output

a [adres]a\ tekst

Voeg de tekst achteraan iedere overeenkomende regel toe.

b [adres1[,adres2]]b[label]

Geen de controle door aan label (het commando dat na het label komt wordt toegepast op de huidige regel. Als er geen label wordt opgegeven worden op deze lijn geen commando's meer uitgevoerd

c [adres1[,adres2]]c\tekst

Vervang (change) de geselecteerde regel met tekst

d [adres1[,adres2]]d

Verwijder de opgegeven regel(s)

D [adres1[,adres2]]D

Verwijder het eerste gedeelte van patronen met meerdere regels (gemaakt met N)

g [adres1[,adres2]]g

Plak de inhoud van de hold space terug in het patroon

G [adres1[,adres2]]G

Hetzelfde als g behalve dat er een newline karakter en de hold space achter het patroon geplakt worden (in plaats van deze te overschrijven)

h [adres1[adres2]]h

Kopieer het patroon in de hold space, de reeds aanwezige informatie in deze buffer zal vernietigd worden. Je kunt met h een regel opslaan voor je deze bewerkt

H [adres[,adres]]H

Voeg achteraan een newline teken toe en plak de inhoud van de pattern space. Zelfs indien deze leeg is zal H een nieuwe regel toevoegen

i [adres]i\ tekst

Voegt de tekst toe voor het overeenkomende adres

l [adres1,[adres2]]l

Toont de inhoud van de pattern space (niet afdrukbare tekens worden als hun ASCII-code weergegeven

n [adres1[,adres2]]n

Lees de volgende regel in de pattern space buffer, de huidige regel wordt weergegeven op standard output

N [adres1[adres2]]N

Voeg de volgende regel achter aan de pattern space toe. De huidige regel wordt van de nieuwe gescheiden door een newline

p [adres1[,adres2]]p

Print de geadresseerde regel

P [adres1[,adres2]]P

Print het eerste deel (tot de ingesloten newline) van een meer-lijnige regel in de patern space (gemaakt met N

Hetzelfde als p als N niet is toegepast op een regel

q [adres]q

Stop (quit) wanneer het adres wordt tegengekomen. De geadresseerde regel wordt eerst weergegeven op de uitvoer (indien dit niet wordt onderdrukt), samen met andere tekst tie eerder is toegevoegd met a of r

r [adres]r bestand

Lees de inhoud van bestand en voeg achteraan de patern space toe. Er moet exact 1 spatie zitten tussen r en de naam van het bestand

s [adres1[,adres2]]s/ patroon /vervang /[vlaggen]

Vervang vervang door patroon voor iedere geadresseerde regel. Als patroon adressen worden gebruikt, betekent het patroon // het laatste adres patroon dat is opgegeven.

De volgende vlaggen kunnen gebruikt worden

n vervang de n-de keer dat patroon voorkomt, n kan ieder nummer zijn binnen het bereik van 1 tot 512

g vervang alle keren dat patroon voorkomt op iedere regel, niet enkel de eerste keer

p Print de regel indien de vervanging succesvol was, indien er meerdere sucessvolle vervangingen waren zal sed deze regel meerdere keren afdrukken

w bestand Schrijf (write) de regel naar bestand als er een vervanging gebeurd is. Er kunnen maximum 10 verschillende bestanden geopend worden

t [adres1,[adres2]]t [label]

Test of er een succesvolle vervanging was op de geadresseerde regels. Indien er een succesvolle vervanging was wordt er gesprongen naar de takt in het label. Indien er geen label wordt gegeven zal er gesprongen worden naar het einde van het script

t is te vergelijken met een case statement in de C/C++ Programmeertaal, of verschillende shell programmeer talen. Er wordt een test gedaan voor iedere case en als er een overeenkomst gevonden wordt springt men naar die "tak" en verlaat je de case-constructie

w [adres1[,adres2]]w bestand

Voeg de inhoud van de pattern space achteraan het bestand in. Deze actie wordt uitgevoerd wanneer het commando wordt tegengekomen en niet wanneer de pattern space wordt afgedrukt. Er moet exact 1 spatie zijn tussen de w en bestandsnaam

Er kunnen maximum 10 bestanden geopend zijn. Het commando zal een nieuw bestand aanmaken indien het niet bestaat, maar de inhoud zal iedere keer dat het script wordt uitgevoerd overschreven worden. Meerdere commando's die uitvoeren naar hetzelfde bestand worden aan het einde van het bestand toegevoegd

x [adres1[,adres2]]x

Vervang de inhoud van de pattern space met de inhoud van de hold space

y [adres1[,adres2]]y/ abc / xyz /

"Vertaal" tekens. Verander iedere a in x, iedere b in y en iedere c in z

Zie ook awk en Regular Expressions

1 NIX wordt vaak gebruikt om te verwijzen naar UNIX® of UNIX-achtige besturingssystemen zoals Linux®, BSD®, macOS®, Solaris®, ...).
2 bepaalde varianten laten opmerkingen overal toe