Sed
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
- De oplossing: http://www.linuxquestions.org/questions/linux-newbie-8/sed-gives-sed-e-expression-1-char-1-unknown-command-%60-947056/
- Toen ik een functie ben gaan gebruiken, verdwenen de problem. Bv.:
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
- http://en.wikipedia.org/wiki/Sed
- http://stackoverflow.com/questions/602706/batch-renaming-with-bash
- http://shri.blog.kraya.co.uk/2010/04/21/linux-bulk-search-and-replace/ - Perfect!
- http://ubuntuforums.org/showthread.php?t=2016104
- http://www.unix.com/shell-programming-and-scripting/31583-wildcards-sed.html
Escape