Wie in een script een tekstbestand zoals configuratiebestanden moet aanpassen, heeft sed (Streaming EDitor) nodig. Sed ontvangt de aan te passen tekst met behulp van een stream (gegevensstroom) afkomstig van andere opdrachten via pipes (> of |) of direct via de grep opdracht zelf. Sed past teksten aan via opties met editoropdrachten, dus zonder de tekst weer te geven.
Naast de vele geavanceerde mogelijkheden heeft sed vijf basisfuncties. Je kunt je dus best eerst concentreren op deze vijf basisfuncties:
Om de werking van sed te demonstreren met voorbeelden, maken we als volgt een voorbeeld tekstbestand aan:
dany@pindabook:~> grep --help | head -25 > grephelp.txt
Het tekstbestand grephelp.txt bevat eerste 25 regels van de instructies om grep te gebruiken.
Zoeken naar een tekstfragment is een standaard functie van elke teksteditor en sed is daarbij geen uitzondering. Laten we onze voorbeeldtekst doorzoeken naar het woord 'PATROON':
dany@pindabook:~> sed -n 's/PATROON/PATROON/p' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt naar PATROON in ieder gegeven BESTAND.
-E, --extended-regexp PATROON is een uitgebreide reguliere expressie
-F, --fixed-strings PATROON is een serie tekenreeksen,
-G, --basic-regexp PATROON is een gewone reguliere expressie (standaard)
-P, --perl-regexp PATROON is een reguliere Perl-expressie
-e, --regexp=PATROON dit PATROON gebruiken bij het zoeken
De -n optie voorkomt het automatisch weergeven (printen) van elke regel. Daardoor worden enkel de regels waarin de zoekterm voorkomt weergegeven. Zonder de -n optie wordt elke regel in de tekst weergegeven en de regels met de zoekterm nogmaals (dus dubbel).
De optie 's/PATROON/PATROON/p'
bestaat uit vier onderdelen gescheiden door schuine strepen (slashes):
Bij het zoeken naar een tekstfragment kan je het gevonden tekstfragment vervangen door een ander tekstfragment met het derde gedeelte van de hierboven besproken zoekopdracht. Een voorbeeld:
dany@pindabook:~> sed -n 's/PATROON/Patroon/p' grephelp.txt
Gebruik: grep [OPTIE...] Patroon [BESTAND...]
Zoekt naar Patroon in ieder gegeven BESTAND.
-E, --extended-regexp Patroon is een uitgebreide reguliere expressie
-F, --fixed-strings Patroon is een serie tekenreeksen,
-G, --basic-regexp Patroon is een gewone reguliere expressie (standaard)
-P, --perl-regexp Patroon is een reguliere Perl-expressie
-e, --regexp=Patroon dit PATROON gebruiken bij het zoeken
In het voorbeeld vervangen we het woord PATROON door het woord Patroon.
Bekijk je echter de inhoud van het bestand grephelp.txt (bijvoorbeeld met de opdracht cat grephelp.txt
dan merk je dat de inhoud van het tekstbestand niet werd aangepast.
De sed opdracht heeft de resultaten standaard enkel weer op het scherm.
Om de aangepaste tekst op te slaan, kan je deze doorsluizen (pipen) naar een nieuw bestand:
dany@pindabook:~> sed 's/PATROON/Patroon/' grephelp.txt > grephelp1.txt
Het bestand grephelp1.txt bevat dan de aangepaste tekst. Door de -n optie te laten vallen, wordt elke regel in het doelbestand geplaatst. En door de p te laten vallen, vermijden we dat elke aangepaste regel tweemaal wordt opgeslagen.
Om de zoekterm te laten vervangen door hetzelfde tekstfragment, kan je het & teken gebruiken. Gewoon zoeken, wordt dan:
dany@pindabook:~> sed -n 's/expressie/&/p' grephelp.txt
-E, --extended-regexp PATROON is een uitgebreide reguliere expressie
-G, --basic-regexp PATROON is een gewone reguliere expressie (standaard)
-P, --perl-regexp PATROON is een reguliere Perl-expressie
Een vervangopdracht waarbij de zoekterm voorkomt in de vervangtekst wordt dan:
dany@pindabook:~> sed -n 's/expressie/&s/p' grephelp.txt
-E, --extended-regexp PATROON is een uitgebreide reguliere expressies
-G, --basic-regexp PATROON is een gewone reguliere expressies (standaard)
-P, --perl-regexp PATROON is een reguliere Perl-expressies
Met deze opdracht wordt het woord expressie vervangen door het woord expressies (meervoud).
Wil je enkel de tweede (of zoveelste) zoekterm vervangen, dan kan je dit eveneens opgeven. Met de volgende opdracht vervang je enkel het tweede voorkomen van het minteken in elke regel door een *:
dany@pindabook:~> sed 's/-/*/2' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt naar PATROON in ieder gegeven BESTAND.
Voorbeeld: grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
-E, *-extended-regexp PATROON is een uitgebreide reguliere expressie
-F, *-fixed-strings PATROON is een serie tekenreeksen,
elke tekenreeks op een aparte regel
-G, *-basic-regexp PATROON is een gewone reguliere expressie (standaard)
-P, *-perl-regexp PATROON is een reguliere Perl-expressie
-e, *-regexp=PATROON dit PATROON gebruiken bij het zoeken
-f, *-file=BESTAND patronen uit dit BESTAND halen
-i, *-ignore-case verschil tussen hoofd- en kleine letters negeren
-w, *-word-regexp patronen komen alleen overeen met een heel woord
-x, *-line-regexp patronen komen alleen overeen met een hele regel
-z, *-null-data regels eindigen op 0-byte, niet op LF-teken
Diversen:
-s, *-no-messages foutmeldingen onderdrukken
-v, *-invert-match de niet-overeenkomende regels selecteren
-V, *-version programmaversie tonen en stoppen
-*help deze hulptekst tonen en stoppen
De s (search en substitute) zorgt dat sed zoekt naar mintekens om deze door * te vervangen. De daaropvolgende 2 zorgt dat enkel het tweede minteken indien aanwezig door een * wordt vervangen. Je ziet in de uitvoer van de hierboven uitgevoerde opdracht duidelijk dat enkel het tweede minteken in elke regel door een * werd vervangen.
Om alle mintekens in de regels door een * te vervangen, gebruik je g (global):
dany@pindabook:~> sed 's/-/*/g' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt naar PATROON in ieder gegeven BESTAND.
Voorbeeld: grep *i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
*E, **extended*regexp PATROON is een uitgebreide reguliere expressie
*F, **fixed*strings PATROON is een serie tekenreeksen,
elke tekenreeks op een aparte regel
*G, **basic*regexp PATROON is een gewone reguliere expressie (standaard)
*P, **perl*regexp PATROON is een reguliere Perl*expressie
*e, **regexp=PATROON dit PATROON gebruiken bij het zoeken
*f, **file=BESTAND patronen uit dit BESTAND halen
*i, **ignore*case verschil tussen hoofd* en kleine letters negeren
*w, **word*regexp patronen komen alleen overeen met een heel woord
*x, **line*regexp patronen komen alleen overeen met een hele regel
*z, **null*data regels eindigen op 0*byte, niet op LF*teken
Diversen:
*s, **no*messages foutmeldingen onderdrukken
*v, **invert*match de niet*overeenkomende regels selecteren
*V, **version programmaversie tonen en stoppen
**help deze hulptekst tonen en stoppen
Je kunt sed-opties ook combineren. Om alle mintekens van het tweede voorkomen in het regel door een * te vervangen, gebruik je:
dany@pindabook:~> sed 's/-/*/2g' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt naar PATROON in ieder gegeven BESTAND.
Voorbeeld: grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
-E, **extended*regexp PATROON is een uitgebreide reguliere expressie
-F, **fixed*strings PATROON is een serie tekenreeksen,
elke tekenreeks op een aparte regel
-G, **basic*regexp PATROON is een gewone reguliere expressie (standaard)
-P, **perl*regexp PATROON is een reguliere Perl*expressie
-e, **regexp=PATROON dit PATROON gebruiken bij het zoeken
-f, **file=BESTAND patronen uit dit BESTAND halen
-i, **ignore*case verschil tussen hoofd* en kleine letters negeren
-w, **word*regexp patronen komen alleen overeen met een heel woord
-x, **line*regexp patronen komen alleen overeen met een hele regel
-z, **null*data regels eindigen op 0*byte, niet op LF*teken
Diversen:
-s, **no*messages foutmeldingen onderdrukken
-v, **invert*match de niet*overeenkomende regels selecteren
-V, **version programmaversie tonen en stoppen
-*help deze hulptekst tonen en stoppen
Om een zoekterm uit de tekst te verwijderen, vervang je deze door niets. Zo verwijder je alle mintekens met de opdracht:
dany@pindabook:~> sed 's/-//g' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt naar PATROON in ieder gegeven BESTAND.
Voorbeeld: grep i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
E, extendedregexp PATROON is een uitgebreide reguliere expressie
F, fixedstrings PATROON is een serie tekenreeksen,
elke tekenreeks op een aparte regel
G, basicregexp PATROON is een gewone reguliere expressie (standaard)
P, perlregexp PATROON is een reguliere Perlexpressie
e, regexp=PATROON dit PATROON gebruiken bij het zoeken
f, file=BESTAND patronen uit dit BESTAND halen
i, ignorecase verschil tussen hoofd en kleine letters negeren
w, wordregexp patronen komen alleen overeen met een heel woord
x, lineregexp patronen komen alleen overeen met een hele regel
z, nulldata regels eindigen op 0byte, niet op LFteken
Diversen:
s, nomessages foutmeldingen onderdrukken
v, invertmatch de nietovereenkomende regels selecteren
V, version programmaversie tonen en stoppen
help deze hulptekst tonen en stoppen
Om een tekstregel toe te voegen na de regel met de gevonden zoekterm gebruik je a (add):
dany@pindabook:~> sed '/--/ a "De vorige regel bevat een dubbel minteken"' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt naar PATROON in ieder gegeven BESTAND.
Voorbeeld: grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
-E, --extended-regexp PATROON is een uitgebreide reguliere expressie
"De vorige regel bevat een dubbel minteken"
-F, --fixed-strings PATROON is een serie tekenreeksen,
"De vorige regel bevat een dubbel minteken"
elke tekenreeks op een aparte regel
-G, --basic-regexp PATROON is een gewone reguliere expressie (standaard)
"De vorige regel bevat een dubbel minteken"
-P, --perl-regexp PATROON is een reguliere Perl-expressie
"De vorige regel bevat een dubbel minteken"
-e, --regexp=PATROON dit PATROON gebruiken bij het zoeken
"De vorige regel bevat een dubbel minteken"
-f, --file=BESTAND patronen uit dit BESTAND halen
"De vorige regel bevat een dubbel minteken"
-i, --ignore-case verschil tussen hoofd- en kleine letters negeren
"De vorige regel bevat een dubbel minteken"
-w, --word-regexp patronen komen alleen overeen met een heel woord
"De vorige regel bevat een dubbel minteken"
-x, --line-regexp patronen komen alleen overeen met een hele regel
"De vorige regel bevat een dubbel minteken"
-z, --null-data regels eindigen op 0-byte, niet op LF-teken
"De vorige regel bevat een dubbel minteken"
Diversen:
-s, --no-messages foutmeldingen onderdrukken
"De vorige regel bevat een dubbel minteken"
-v, --invert-match de niet-overeenkomende regels selecteren
"De vorige regel bevat een dubbel minteken"
-V, --version programmaversie tonen en stoppen
"De vorige regel bevat een dubbel minteken"
--help deze hulptekst tonen en stoppen
"De vorige regel bevat een dubbel minteken"
Om een regel voor de gevonden zoekterm in te voegen, gebruik je i (insert):
dany@pindabook:~> sed '/--/ i "De volgende regel bevat een dubbel minteken"' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt naar PATROON in ieder gegeven BESTAND.
Voorbeeld: grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
"De volgende regel bevat een dubbel minteken"
-E, --extended-regexp PATROON is een uitgebreide reguliere expressie
"De volgende regel bevat een dubbel minteken"
-F, --fixed-strings PATROON is een serie tekenreeksen,
elke tekenreeks op een aparte regel
"De volgende regel bevat een dubbel minteken"
-G, --basic-regexp PATROON is een gewone reguliere expressie (standaard)
"De volgende regel bevat een dubbel minteken"
-P, --perl-regexp PATROON is een reguliere Perl-expressie
"De volgende regel bevat een dubbel minteken"
-e, --regexp=PATROON dit PATROON gebruiken bij het zoeken
"De volgende regel bevat een dubbel minteken"
-f, --file=BESTAND patronen uit dit BESTAND halen
"De volgende regel bevat een dubbel minteken"
-i, --ignore-case verschil tussen hoofd- en kleine letters negeren
"De volgende regel bevat een dubbel minteken"
-w, --word-regexp patronen komen alleen overeen met een heel woord
"De volgende regel bevat een dubbel minteken"
-x, --line-regexp patronen komen alleen overeen met een hele regel
"De volgende regel bevat een dubbel minteken"
-z, --null-data regels eindigen op 0-byte, niet op LF-teken
Diversen:
"De volgende regel bevat een dubbel minteken"
-s, --no-messages foutmeldingen onderdrukken
"De volgende regel bevat een dubbel minteken"
-v, --invert-match de niet-overeenkomende regels selecteren
"De volgende regel bevat een dubbel minteken"
-V, --version programmaversie tonen en stoppen
"De volgende regel bevat een dubbel minteken"
--help deze hulptekst tonen en stoppen
Om de volledige regel met de zoekterm te vervangen, gebruik je c (change):
dany@pindabook:~> sed '/PATROON/ c Deze regel bevat geheime informatie' grephelp.txt
Deze regel bevat geheime informatie
Deze regel bevat geheime informatie
Voorbeeld: grep -i 'hallo wereld' menu.h main.c
Keuze en interpretatie van het patroon:
Deze regel bevat geheime informatie
Deze regel bevat geheime informatie
elke tekenreeks op een aparte regel
Deze regel bevat geheime informatie
Deze regel bevat geheime informatie
Deze regel bevat geheime informatie
-f, --file=BESTAND patronen uit dit BESTAND halen
-i, --ignore-case verschil tussen hoofd- en kleine letters negeren
-w, --word-regexp patronen komen alleen overeen met een heel woord
-x, --line-regexp patronen komen alleen overeen met een hele regel
-z, --null-data regels eindigen op 0-byte, niet op LF-teken
Diversen:
-s, --no-messages foutmeldingen onderdrukken
-v, --invert-match de niet-overeenkomende regels selecteren
-V, --version programmaversie tonen en stoppen
--help deze hulptekst tonen en stoppen
Bij transformaties (omvormen) kan je letters door andere letters vervangen, bijvoorbeeld om kleine letters naar hoofdletters om te zetten:
dany@pindabook:~> sed 'y/a/A/' grephelp.txt
Gebruik: grep [OPTIE...] PATROON [BESTAND...]
Zoekt nAAr PATROON in ieder gegeven BESTAND.
Voorbeeld: grep -i 'hAllo wereld' menu.h mAin.c
Keuze en interpretAtie vAn het pAtroon:
-E, --extended-regexp PATROON is een uitgebreide reguliere expressie
-F, --fixed-strings PATROON is een serie tekenreeksen,
elke tekenreeks op een ApArte regel
-G, --bAsic-regexp PATROON is een gewone reguliere expressie (stAndAArd)
-P, --perl-regexp PATROON is een reguliere Perl-expressie
-e, --regexp=PATROON dit PATROON gebruiken bij het zoeken
-f, --file=BESTAND pAtronen uit dit BESTAND hAlen
-i, --ignore-cAse verschil tussen hoofd- en kleine letters negeren
-w, --word-regexp pAtronen komen Alleen overeen met een heel woord
-x, --line-regexp pAtronen komen Alleen overeen met een hele regel
-z, --null-dAtA regels eindigen op 0-byte, niet op LF-teken
Diversen:
-s, --no-messAges foutmeldingen onderdrukken
-v, --invert-mAtch de niet-overeenkomende regels selecteren
-V, --version progrAmmAversie tonen en stoppen
--help deze hulptekst tonen en stoppen
Hierbij worden alle kleine letters a naar hoofdletter A omgezet. Om verschillende letters gelijktijdig om te zetten, gebruik je letterreeksen. Let daarbij wel op de volgorde van de letters:
dany@pindabook:~> sed 'y/abdg/ABDG/' grephelp.txt
GeBruik: Grep [OPTIE...] PATROON [BESTAND...]
Zoekt nAAr PATROON in ieDer GeGeven BESTAND.
VoorBeelD: Grep -i 'hAllo werelD' menu.h mAin.c
Keuze en interpretAtie vAn het pAtroon:
-E, --extenDeD-reGexp PATROON is een uitGeBreiDe reGuliere expressie
-F, --fixeD-strinGs PATROON is een serie tekenreeksen,
elke tekenreeks op een ApArte reGel
-G, --BAsic-reGexp PATROON is een Gewone reGuliere expressie (stAnDAArD)
-P, --perl-reGexp PATROON is een reGuliere Perl-expressie
-e, --reGexp=PATROON Dit PATROON GeBruiken Bij het zoeken
-f, --file=BESTAND pAtronen uit Dit BESTAND hAlen
-i, --iGnore-cAse verschil tussen hoofD- en kleine letters neGeren
-w, --worD-reGexp pAtronen komen Alleen overeen met een heel woorD
-x, --line-reGexp pAtronen komen Alleen overeen met een hele reGel
-z, --null-DAtA reGels einDiGen op 0-Byte, niet op LF-teken
Diversen:
-s, --no-messAGes foutmelDinGen onDerDrukken
-v, --invert-mAtch De niet-overeenkomenDe reGels selecteren
-V, --version proGrAmmAversie tonen en stoppen
--help Deze hulptekst tonen en stoppen
Om de aanpassingen in het bestand zelf door te voeren, gebruik je de -i optie (in-place). Om bijvoorbeeld het woord PATROON door Patroon in het tekstbestand zelf te vervangen, gebruik je:
Oefening baart kunst en ontdek de kracht van de sed opdracht.