Sed: verschil tussen versies

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen
Regel 15: Regel 15:
 
== Find & replace: 's' ==
 
== Find & replace: 's' ==
  
Het commando </code>s</code> staat voor ''substitute'' -- Vervangen
+
Het commando <code>s</code> staat voor ''substitute'' -- Vervangen
 
Voorbeelden:
 
Voorbeelden:
  

Versie van 19 sep 2018 23:16

sed (stream editor) is een Unix-utility en programmeertaal om tekst te parsen oftewel te stream editen, inclusief find & replace. Andere tools zijn AWK en Perl

Direct

Je kunt sed gebruiken vanaf de command line, dus zonder gebruik te maken van een apart input-bestand. Da's handig. Voorbeeld:

# Vervang de string "from here ... to here" met de tekst "OVER THERE"
#
echo 'aksjfhd from here fooo asdlfkjaslkfjd to here aslfjdlaksjdf' | sed 's/from here.*to here/OVER THERE/'

aksjfhd OVER THERE aslfjdlaksjdf

Find & replace: 's'

Het commando s staat voor substitute -- Vervangen Voorbeelden:

sed 's/input/output/' test.txt    # In bestand test.txt wodt 'input' vervangen door 'output. Resultaat > console. Trailing / verplicht

sed -i 's/input/output/' test.txt # Als hierboven, maar resultaat > test.txt.

sed 's/input/output/I' test.txt   # I = case sensitive

sed 's/input/output/g' test.txt   # g = global substitute: Alle occurences worden vervangen

Find & replace met apart input-bestand

Vertalingen zitten in bestand Vertalingen.txt. Te vertalen tekst zit in bestand database.sql. Commando:

 sed -f Vertalingen.txt -i database.sql

En hier is een impressie van bestand Vertalingen.txt:

###########################
# Langste zinnen eerst
###########################

s/met automatische stop/mit automatischer Abschaltung/  # Grammatica?
s/koolborstel voorbeeld/Kohlebürste Beispiel/
s/Koolborstels voor/Kohlebürsten für/I	                # Case-insensitive, want in het Duits altijd met een hoofdletter
s/Koolborstel voor/Kohlebürste für/I	                # Case-insensitive, want in het Duits altijd met een hoofdletter

###########################
# Losse relatief lange woorden
###########################

s/Koolborstels/Kohlebürsten/	# Eerst meervoud want langere term, dan pas enkelvoud!
s/Koolborstel/Kohlebürste/

###########################
# Soorten handgereedschap
###########################

s/Angle grinder/Winkelschleifer/
s/Angular drill/Winkelbohrmaschine/
s/Angular grinder/Winkelschleifer/
s/Band sander/Bandschleifer/
s/Cutter/Schneider/
s/Belt sander/Bandschleifer/
s/Bench cutter/Bank Schneider/

Apostrophes, dubbele aanhalingstekens en foutmeldingen

replacecmd(){

   sed -i "s|$1|$2|" "$3"
}

met de argumenten van de aanroep tussen dubbele aanhalingstekens:

replacecmd "$sedstring1" "$sedstring2" "$sedbestand"

Escape characters

Escapen gaat met terugschrap (\). Standaard-karakters die je moet escapen:

$.*[\]^

Daarnaast geven apostrophes en schuine strepen soms problemen.

schrap (/)

Eén oplossing: pipes gebruiken als scheidingsteken in de regex ipv. schuine strepen:

sed 's|/test/|geentest|' test.txt

maar da's geen universele oplossing.

Spatie

Lijkt geen probleem te zijn, en spaties worden ook niet genoemd in rijtjes met characters die escaped moeten worden:

echo 'dit is de in put in deze regel' | sed 's/in put/out put/'

Apostrophe

In beginsel hoeven apostrophes niet ge-escape'd te worden. Bv.:

#!/bin/sh

invoer="Het woord Referenciasproductosalternativo-ID's zit in deze string"

expressie="s/'/+/g"

echo "\n\nInvoer: $invoer"
echo "Expressie: $expressie"

echo "Uivoer: $invoer" | sed $expressie
echo "Uivoer: $invoer" | sed -r $expressie # Zelfde resultaat. Hier is -r dus niet nodig

Apostrophes kunnen wel een rol spelen in de programmeeromgeving waar je met sed bezig bent. In het voorbeeld hierboven is daar rekening mee gehouden, door de tring met dubbele aanhalingstekens te omsluiten.

Terugschrap (backslash, \)

Die moet je soms drie keer escapen:

#!/bin/sh

invoer="Het woord Referenciasproductosalternativo-ID\'s zit in deze string"

expressie="s/\\\/+/g"

echo "\n\nInvoer: $invoer"
echo "Expressie: $expressie"

echo "Uivoer: $invoer" | sed $expressie
echo "Uivoer: $invoer" | sed -r $expressie

Waarom? Nou hierom.

Maar soms weer niet: Bij automatisch vertalen van documenten gebruik ik deze regel:

sed -f vertalingen.txt -i vertaal.sql

en daarbij moest ik dit gebruiken als expressie:

s/Referenciasproductosalternativo-ID\\'s/Referencia producto/g

--> Vuistregel: \\ gebruiken.

Apostrophe én backslash

Da's nu simpel:

#!/bin/sh

invoer="Het woord Referenciasproductosalternativo-ID\'s zit in deze string"

expressie="s/\\\'/+/g"

echo "\n\nInvoer: $invoer"
echo "Expressie: $expressie"

echo "Uivoer: $invoer" | sed $expressie
echo "Uivoer: $invoer" | sed -r $expressie

Syntaxis

sed -i

Optie -i geeft aan dat de oorspronkelijke bron moet worden overschreven

sed -e

Optie -e geeft aan dat de expressie direct hierna volgt. Kan vaak weggelaten worden

sed -f

Lees commando's uit een bestand

Zie ook

Bronnen

Escape