Prolog
Välkommen till fortsättningen av Open Source och möjligheterna med Cygwin.
Här fortsätter artikelserien om SED. Detta är del 3.
SED del 1 och del 2 har varit på en teoretisk- och introduktionsnivå.
Lite koncept och syntax har visats.
Om du följer artikeln “Open Source – Take me to the (promi)SED land ! Del 1.” så får du en introduktion och en inblick i denna artikelserie.
I föregående artikel fick du följa med och se vad SED kan användas till. Denna artikel skall ta oss ett steg vidare. Artikelserien kommer stegvis att öka i svårighetsgrad men också i nyttograd.
Jag har jobbat en hel del under årens lopp med information som skall in i en databas, ofta har jag fått informationen i text-format.
Ungefär 11 gånger av 10 så måste innehållet i filen “tvättas” eller på annat sätt justeras.
I enkla fall kan man öppna filen i en text-editor som tex Notepad++, Notepad, Wordpad, VI eller Emacs och göra en sök-och-ersätt.
Om strukturen på informationen är komplex och filen i sig är stor, då är det inte lika lätt att använda ovan nämnda editorer pga begränsningar i verktyget.
Jag har försökt öppna en fil som var 3 GB stor i Notepad, utan större framgång, applikationen hängde sig rejält. När jag däremot körde den i min Cygwin-emulator och använde mig av SED så gick det alldeles utmärkt.
SED löser detta utan problem.
SED är också användbart tex om man gör en sökning i en databas där resultatet senare skall användas för att tex skapa ny sql-kod.
Jag kan nog inte trycka för mycket på betydelsen av SED, dels för mig personligen men dels för andra användare av SED.
För min egen del så är SED det kommando som jag utan tvekan använder mest i Unix, om jag inte har tillgång till en Unix-maskin, ja då kan jag ju använda Cygwin.
Till dig läsare vill jag bara säga “follow me to the (promi)SED land …”
Diskussion/Exempel
I del 2 i artikelserien fick vi en introduktion till reguljära uttryck (Regular expression).
Reguljära uttryck är en av de viktigaste delarna att lära sig när det gäller SED, tyvärr så är svårighetsgraden för de flesta ganska så hög, dvs det uppfattas av många som en hög tröskel att ta sig över.
Vi skall titta på ett exempel som har en ganska komplex struktur.
Vårt exempel ser ut enligt följande:
File / Database Object : Procedure->JourneyPattern_Refresh
Status : 17 SQL Scanned
Valid SQL : 6
Problematic SQL : 3
Complex SQL : 0
Simple SQL : 3
File Size (Bytes) : 10704
Started At : 8/24/2010 11:36:17 AM
Processing Time (HH:MM:SS) : 00:00:14
Vår exempel fil har 363 textstycken enligt ovan struktur.
Det som skiljer sig åt är det som står till höger om respektive kolon :
I vissa fall är det lika värden och i andra fall är det olika.
Det vi vet garanterat i vårt fall är att värdet till höger om
File / Database Object : Procedure->
garanterat är unikt.
De tre första styckena ser ut som följer:
File / Database Object : Procedure->JourneyPattern_Refresh
Status : 17 SQL Scanned
Valid SQL : 6
Problematic SQL : 3
Complex SQL : 0
Simple SQL : 3
File Size (Bytes) : 10704
Started At : 8/24/2010 11:36:17 AM
Processing Time (HH:MM:SS) : 00:00:14
File / Database Object : Procedure->diiStopPoint_Select
Status : 12 SQL Scanned
Valid SQL : 11
Problematic SQL : 10
Complex SQL : 0
Simple SQL : 1
File Size (Bytes) : 13925
Started At : 8/24/2010 11:36:50 AM
Processing Time (HH:MM:SS) : 00:00:14
File / Database Object : Procedure->StopPoint_SaveVersion
Status : 12 SQL Scanned
Valid SQL : 12
Problematic SQL : 1
Complex SQL : 3
Simple SQL : 8
File Size (Bytes) : 7618
Started At : 8/24/2010 11:42:10 AM
Processing Time (HH:MM:SS) : 00:00:04
När vi är klar så vill vi ha ett resultat som ser ut så här:
File / Database Object : Procedure->JourneyPattern_Refresh
File / Database Object : Procedure->diiStopPoint_Select
File / Database Object : Procedure->StopPoint_SaveVersion
Vi måste således göra en/flera operationer som tar bort samtliga rader som börjar med
Status :
Valid SQL :
Problematic SQL :
Complex SQL :
Simple SQL :
File Size (Bytes) :
Started At :
Processing Time (HH:MM:SS) :
Vi kan formulera vårt arbete på följande sätt:
Ta bort samtliga rader i filen som börjar med “Status”. Spara filen.
Tag därefter bort samtliga rader i filen som börjar med “Valid SQL”. Spara filen.
Tag därefter bort samtliga rader i filen som börjar med “Problematic SQL”. Spara filen.
Tag därefter bort samtliga rader i filen som börjar med “Complex SQL”. Spara filen.
Tag därefter bort samtliga rader i filen som börjar med “Simple SQL”. Spara filen.
Tag därefter bort samtliga rader i filen som börjar med “File Size”. Spara filen.
Tag därefter bort samtliga rader i filen som börjar med “Started At”. Spara filen.
Tag därefter bort samtliga rader i filen som börjar med “Processing Time”. Spara filen.
eller på följande sätt:
Tag bort samtliga rader som börjar med “Status” och ta bort alla rader fram till och med de rader som börjar med “Processing Time”. Spara filen.
Första sättet är det absolut enklaste sättet, det kräver inte särskilt mycket SED kunskap. Däremot innefattar den flera steg, som i sin tur kan krångla.
Det andra sättet är betydligt mer komplicerat, kräver mer SED kunskap, innefattar mindre steg.
Vi skall titta på bägge metoder.
Antag att vår fil heter resultat_fil.txt, den har 3634 rader.
FÖRSTA METODEN:
Vi använder oss av
sed ‘/pattern/d’
som innebär att man tar bort samtliga rader som uppfyller pattern.
Detta måste göras för varje rad som uppfyller pattern, dvs har vi ett mönster med 8 unika strängar så måste vi således göra detta 8 gånger.
(Vårt exempel har 8 unika strängar vars rader vi skall ta bort)
1) sed ‘/Status/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
2) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller ordet “Status” borttagen.
3) sed ‘/Valid SQL/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
4) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller strängen “Valid SQL” borttagen.
5) sed ‘/Problematic SQL/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
6) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller strängen “Problematic SQL” borttagen.
7) sed ‘/Complex SQL/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
8 ) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller strängen “Complex SQL” borttagen.
9) sed ‘/Simple SQL/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
10) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller strängen “Complex SQL” borttagen.
11) sed ‘/File Size/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
12) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller strängen “Complex SQL” borttagen.
13) sed ‘/Started At/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
14) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller strängen “Complex SQL” borttagen.
15) sed ‘/Processing Time/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
16) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader som innehåller strängen “Complex SQL” borttagen.
17) KLART, nu är filen städad och de önskade raderna är borttagna.
ANDRA METODEN:
Vi använder oss av
sed ‘/pattern_1/,/pattern_2/d’
som innebär att man tar bort samtliga rader mellan pattern_1 och pattern_2, samt raderna som innehåller pattern_1, samt raderna som innehåller pattern_2.
Detta görs endast en gång, dvs har vi ett mönster med 8 unika strängar så måste vi således göra detta 1 gång genom att definiera starten på mönstret respektive slutet på mönstrat.
1) sed ‘/Status/,/Processing Time/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
2) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
Nu är samtliga rader borttagna mellan pattern_1 och pattern_2, samt raden som innehåller pattern_1, samt raden som innehåller pattern_2.
3) KLART, nu är filen städad och de önskade raderna är borttagna.
STÄDNINGEN FORTSÄTTER:
Gemensamt för de två metoderna vi sett ovan är att vi skall fortsätta städa i filen.
Vi vill inte ha tomma rader i filen, vi måste alltså ta bort de tomma raderna.
Vi vill inte ha något mellanslag/tab/mellanrum i början av respektive rad, vi måste alltså ta bort mellanslag/tab/mellanrum i början av respektive rad.
Vi vill inte ha något mellanslag/tab/mellanrum i slutet av respektive rad, vi måste alltså ta bort mellanslag/tab/mellanrum i slutet av respektive rad.
Ta bort tomma rader
1) sed ‘/^$/d’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
2) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
3) KLART, nu är samtliga tomma rader borttagna.
Ta bort mellanslag/tab/mellanrum i början av respektive rad
1) sed ’s/^[ \t]*//’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
2) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
3) KLART, nu är samtliga mellanslag/tab/mellanrum i början av respektive rad borta.
Ta bort mellanslag/tab/mellanrum i slutet av respektive rad
1) sed ’s/[ \t]*$//’ resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
2) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
3) KLART, nu är samtliga mellanslag/tab/mellanrum i slutet av respektive rad borta.
Kombinera de tre operationerna
En av SED:s egenskaper är att man bland annat kan kombinera ihop operationer till en enda operation.
Vilket för oss skulle innebära att vi gör en körning istället för tre körningar.
Ett sätt att lösa detta är att använda sig av en skript-fil som input till SED.
Operationen för respektive anrop ser ut som följer:
| Beskrivning |
Syntax |
| Ta bort tomma rader |
/^$/d |
| Ta bort mellanslag/tab/mellanrum i början av respektive rad |
s/^[ \t]*// |
| Ta bort mellanslag/tab/mellanrum i slutet av respektive rad |
s/[ \t]*$// |
För att kombinera ihop två eller fler operationer så kan man skapa en text-fil där man anger respektive operation på en egen rad, dvs om man har tre operationer då kommer vår text-fil att ha tre rader osv.
Jag skapar en text-fil som heter bulk_script.txt
med följande tre rader:
/^$/d
s/^[ \t]*//
s/[ \t]*$//
Syntaxen för SED med en skript-fil ser ut som följer:
sed -f SCRIPT_FILE < ORIGINAL_FILE > RESULT_FILE
Ta bort tomma rader samt ta bort mellanslag/tab/mellanrum i slutet av respektive rad samt ta bort mellanslag/tab/mellanrum i början av respektive rad
1) sed -f bulk_script.txt < resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
2) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
3) KLART, nu är tomma rader borta samt mellanslag/tab/mellanrum i slutet av respektive rad borta och alla mellanslag/tab/mellanrum i början av respektive rad borta.
Nu kör vi med en skript-fil för allt vi skulle göra
Skript-filens möjligheter med SED gör att vi på ett effektivt sätt kan förenkla körningarna och få en bättre överblivk vad som händer samt en bättre förståelse för den kronologiska följden.
Vårt sista exempel i denna artikel skall visa oss hur vi kan göra samtliga operationer vid en och endast en körning.
Vi skall rensa bort mönstret som finns i vår ursprungsfil.
Vi skall ta bort tomma rader.
Vi skall ta bort mellanslag/tab/mellanrum i början av respektive rad.
Vi skall ta bort mellanslag/tab/mellanrum i slutet av respektive rad.
Det skall vi göra med hjälp av en skript-fil och dessutom göra detta på en och endast en körning.
Vår skript-fil som heter bulk_script.txt innehåller följande:
/Status/,/Processing Time/d
/^$/d
s/^[ \t]*//
s/[ \t]*$//
Vår sista körning kommer nu att se ut så här:
1) sed -f bulk_script.txt < resultat_fil.txt > resultat_fil.txt.tmp
Resultatet av denna körning sparas i en temporär fil som jag kallar resultat_fil.txt.tmp
2) mv resultat_fil.txt.tmp resultat_fil.txt
Skriv över orginalfilen resultat_fil.txt med innehållet i resultat_fil.txt.tmp
3) KLART.
När man jobbar med flera steg i en text-fil så är det klokt att dela upp arbetet i mindre steg och dessutom använda sig av en skript-fil.
Det finns flera fördelar med det arbetssättet.
Den kraftfullaste är att man får en mycket bra översikt samt att förändringar kan göras på ett enklare sätt eftersom man har den kronologiska ordningen i filen.
Epilog
Du har nu fått en fortsättning på SED, det här är del 3 i artikelserien om “Open Source – Take me to the (promi)SED land”.
Jag hoppas att speciellt denna artikel, dvs den tredje artikeln om SED har fått dig att inse kraften i SED. Jag läste på en webb-sida om SED där man förklarade varför just SED är förhållandevis okänt, även för den inbitne Unix/Linux-fantasten. Förklaringen var ganska enkel, det handlade kort och gott om dokumentationen. Prova vid Unix/Linux-prompten skriva “man sed” (dvs visa manual-sidan för SED), troligtvis blir du mer förvirrad nu än vad du kanske är i vanliga fall. Den dokumentation man kan hitta om SED är till största del erfarenheter och exempel-kod från personer som på egen hand gjort dessa lathundar. Om man föredrar mer formell dokumentation, ja då är du hänvisad till SED:s manual-sidor, med allt vad det innebär.
Artikelserien om “Open Source – Take me to the (promi)SED land” kommer att fortsätta med en fjärde avslutande del, där vi fortsätter i samma anda som denna artikel, dvs det finns ett exempel med en informations-fil som vi skall jobba med.
Vi har nu läst och följt med i tre artiklar om SED, där svårigheten har ökat hela tiden. Min förhoppning med denna artikelserie är att du skall få en känsla och en förståelse över SED och inte just bara mekaniska kunskaper där du kopierar färdiga operationer. Kopieringen av färdiga operationer är viktigt men för att underlätta för dig framöver så är det ännu bättre om du kan få med dig en känsla och bättre förståelse.
Därför skriver jag denna artikelserie.
Jag kan inte låta bli att återigen trycka på att SED är oerhört kraftfullt och hjälper dig rejält.
Welcome to the (promi)SED land !
Länkar
Notepad++
Open Source – Take me to the (promi)SED land ! Del 1.
Reguljära uttryck (Regular Expression)
Using the SED editor in Linux
AWK: The Linux Administrators’ Wisdom Kit
Cygwin
Dagens hälsning från Anders

(Anders till vänster och Bosse den Franska Bulldoggen till höger)