Mer om tekstbaserte verktøy og shellprogrammering i Linux
Tekstbaserte verktøy / filterprogrammer Vi skal se nærmere på tekstfiltrene: grep (og regulæruttrykk) sort uniq tr (og litt tekstanalyse) sed (og litt om vedlikehold av store datamengder) cut (og systemdata, brukerdata og shellfunksjoner) diff
grep: Søking i tekstlige data grep* er et verktøy som finnes i alle Unix-lignende OS grep [OPTIONS] PATTERN [FILE...] Leser en eller flere tekstfiler, eller standard input hvis ingen filer er angitt, linje for linje Linjene sammenlignes med et søkemønster som angis som et regulæruttrykk Hvis en lest linje matcher/inneholder søkemønsteret, skrives den ut til standard output Linjer som ikke matcher, skrives ikke ut reduserer en stor mengde informasjon til en liten mengde nyttig informasjon grep har mange opsjoner for å «skreddersy» virkemåten *: Navnet kommer fra tidlig Unix-historie
Noen vanlige opsjoner til grep c count Antall linjer i input som matcher i ignore Ikke case-sensitiv l list files Skriv bare ut filnavn w word Let bare etter hele ord n number Skriv ut linjenummere i filen(e) v invert Skriv ut linjer som ikke matcher q quiet Ingen output, exit (0) hvis match E extend Bruk Extended Regular Expressions (egrep er det samme som grep E)
Regulæruttrykk / Regular Expressions Formell (eg. matematisk) beskrivelse av hvorledes mønstre for søking i tekst kan angis Brukes i mange applikasjoner der det er behov for søke- og søk/erstatt-operasjoner, f.eks. editorer, databasesystemer og ulike browsere Ulike varianter av regulæruttrykk med ulik syntaks, bl.a.: BRE: Basic Regular Expressions ERE: Extended Regular Expressions PCRE: Perl Compatible Regular Expressions
Grunnleggende begreper Et regulæruttrykk (regexp) er en sekvens av tegn som beskriver et tegnmønster. Tegnene i et regexp er enten: Vanlige tegn som bare «matcher seg selv», eller: Metategn som har en spesiell betydning En regexp prosesseres av en regexp-maskin (programvare) som matcher en regexp mot en gitt tekststreng Vi får en match hvis tekststrengen inneholder tegnmønsteret som regulæruttrykket beskriver
Noen metategn i (extended) regexp. Matcher alle tegn unntatt NEWLINE? Null eller én forekomst av forrige tegn * Null eller flere forekomster av forrige tegn + En eller flere forekomster av forrige tegn \ Ikke behandle neste tegn som metategn [] Ett av tegnene angitt mellom [ og ] [^] Ett av tegnene ikke angitt mellom [^ og ]
Eksempler regexp matcher H..berg Høiberg Hxxberg H12berg... Høi?berg Høberg Høiberg Høi*berg Høberg Høiberg Høiiiiiiiiberg... Høi+berg Høiberg Høiiberg Høiiiiiiiiberg... H\\\*berg H\*berg H[abc][0 9] Ha0 Hb1 Hc7 Ha4... H[^d o]iberg Høiberg Haiberg HCiberg H8iberg... H[a z]* H Haaaa Habcdefg Hzzzzaaa...
Noen flere metategn i regexp ^ Begynnelse på en linje $ Slutten på en linje \< Begynnelse på et ord \> Slutten på et ord Et av tegnene på hver side av (or) () Gruppering inne i en regexp, for presedens {n} Nøyaktig n forekomster av forrige tegn {n,m} Minst n og høyst m forekomster av forrige tegn {n,} n eller flere forekomster av forrige tegn
Eksempler regexp matcher ^Jan Jan er en hyggelig fyr Jan$ Linuxnerden heter Jan \<know I have knowledge about this known\> This is unknown to me \<know\> I know the truth gr(a e)y gray grey ab{2} abb ab{2,} abb abbb abbbbbb... a(bc){2,4} abcbc abcbcbc abcbcbcbc
Noen grep-eksempler Antall «gamle» Unix-kommandoer på bare to tegn: ls /bin grep c '^[a z][a z]$ Bruker grep på ordlisten i /usr/share/dict/words: Alle ord på tre tegn med bare konsonanter: egrep i "^[^aeiouy']{3}$" Alle ord på tre tegn med bare vokaler: egrep i "^[aeiouy]{3}$" Alle ord som begynner med qu og slutter med y: grep i "^qu[a z]*y$" Alle ord som inneholder alle vokalene i alfabetisk rekkefølge: grep i "a[a z]*e[a z]*i[a z]*o[a z]*u[a z]*y"
sort: Sortering av linjer med tekst Hovedbruksområder: Sortering av enkeltfiler og i pipelines Samsortering av flere filer Sjekke om en fil allerede er sortert Fletting (ikke sortering) av allerede sorterte filer sort er ikke veldig rask*: Bruker temporærfiler underveis i sorteringen Sortering av svært store datamengder bør gjøres med annen programvare enn Linux sort sort er svært fleksibel med mange opsjoner * Sorteringsalgoritmen som brukes i GNU-Linux er flettesortering/merge sort
Sorteringskriterier Default sort uten opsjoner: Sorterer hele linjer på «tegnverdi» i stigende rekkefølge Tegn på begynnelsen av linjene er mest signifikant Whitespace ignoreres Sorteringsrekkefølge (alfanumeriske tegn): Siffer før bokstaver Bokstaver sorteres alfabetisk Små bokstaver foran store bokstaver Mange opsjoner til sort for å endre sorteringskriteriet, slik at f.eks. tall sorteres korrekt
Endring av sorteringskriteriet n numeric Sorterer tall riktig h human Skjønner tall som f.eks 1K og 2G r reverse Sorterer i omvendt rekkefølge f fold Ikke case-sensitiv M month Sorterer månedsnavn riktig kn kolonne Sorterer mhp. kolonne nr n på linjene*, kolonner er default space-separert tc separator Angir at tegnet c skiller kolonnene i stedet for space *: Sorteringskriterier kan angis lokalt for hver kolonne
sort: eksempler Sortering av en fil, med default kriterier: sort sort_test_1 Kolonnevis sortering av en fil: sort k4nr k5 sort_test_2 Sortering av filinformasjon etter størrelse: ls l sort k5nr Sortering av brukerdatabasen på ask.hiof.no: ypcat passwd sort t: k5 more ypcat passwd sort t: k3n more
Noen flere opsjoner til sort o Skriv output til fil (overskriving) c Bare sjekk om fil er sortert, ikke sortér m Flett sammen sorterte filer, ikke sortér Feiler hvis usorterte filer u Filtrér ut like påfølgende linjer S Sett størrelsen på RAM-bufferet som brukes til sortering (for store jobber)
uniq: Fjerning av duplikater Hvis flere påfølgende linjer i input er like, vil uniq kun skrive ut den reperte linjen én gang uniq finner ikke like linjer i input hvis de ikke kommer rett etter hverandre: Sortér input først og pipe videre til uniq Eller bruk sort u Har opsjoner for å: Endre virkemåte og output Ignorere deler av linjene ved sammenligning
Noen opsjoner til uniq c count Skriv antall ganger linjen er repetert u unique Bare skriv linjer som ikke repeteres d repeated Bare skriv linjer som repeteres sn skip-char Ignorér første n tegn på hver linje fn skip-field Ignorér første n felt på hver linje wn check Bare sjekk første n tegn på hver linje
uniq: Eksempel To datafiler for kursene Op.sys. og Datakom. høsten 2014, med navn på alle studentene i hvert kurs Alle studentene i begge kurs: sort ITF22514_OS ITF20205_DK uniq Alle studenter som tar både Op.sys. og Datakom.: sort ITF22514_OS ITF20205_DK uniq d Alle studenter som bare tar ett av kursene: sort ITF22514_OS ITF20205_DK uniq u Alle studenter og antall kurs de tar: sort ITF22514_OS ITF20205_DK uniq c
tr: Bytt og fjern tegn i input Leser standard input tegn for tegn «Redigerer» tegnene etter gitte regler før utskrift til standard output: Kan bytte ut alle tegn i en angitt tegnmengde med korresponderende tegn i en annen tegnmengde Kan fjerne angitte tegn fra input Kan «klemme sammen» påfølgende forekomster av et tegn eller en gruppe tegn i input, til et enkelt tegn i output Håndterer spesialtegn og «non-printables» i både input og output (linjeskift, tab, backspace...)
tr: Syntaks tr [OPTION]... SET1 [SET2] SET1 er en samling tegn der hvert tegn byttes med tegnet i samme posisjon i SET2 SET kan angis som: Eksplisitt liste av tegn: abcdef 0123 xxyyzz Sekvens av påfølgende tegn: a z A Z 0 9 i m Spesialmengder som f.eks. [:alnum:] mengden av alle bokstaver og siffer Spesialtegn angis f.eks. slik: "\n" "\t" new line horizontal tab
tr: Opsjoner d delete Fjern alle tegn som er i SET1 (SET2 skal ikke angis) c complement Bruk alle tegn som ikke er i SET1 som SET1 s squeeze Flere forekomster rett etter hverandre av et av tegnene i SET1, skal erstattes med kun én forekomst av det motsvarende tegnet i SET2
tr: Eksempler tr abc def tr abc d tr 0 9 X tr s 0 9 X tr d A Z tr c 0 9 X Bytt ut a med b, b med e og c med f Bytt ut a, b og c med d Bytt ut alle siffer med X «Skvis» påfølgende siffer sammen til én X Fjern alle store bokstaver fra input Bytt ut alt(!) som ikke er siffer med X tr ' ' "\t" Bytt ut SPACE med TAB tr cs A Za z "\n" Bytt ut alle påfølgende tegn som ikke er engelske bokstaver med ett enkelt linjeskift
Et shellprogram for «tekstanalyse» Program som har to parametre: Navn på en tekstfil Et positivt heltall n Programmet skal: Lese gjennom hele tekstfilen Bruke tr, sort og uniq til å finne og skrive ut de n mest brukte ordene i teksten, sammen med antall ganger hvert ord forekom
Tekstanalyse: Implementasjon Bruk tr til å splitte opp de innleste tekstlinjene i enkeltord skrevet med små bokstaver, med ett ord på hver linje Sorter ordene alfabetisk med sort Bruk uniq c til å telle hvor mange ganger hvert ord forekommer Sorter ordene med sort etter antall forekomster, i omvendt numerisk rekkefølge Bruk head til å bare skrive ut de n meste brukte Shellprogram: lwf list word frequencies
sed: stream editor Utfører (relativt) enkle transformasjoner/ redigeringskommandoer på en tekststrøm Tekststrøm: Tekstlige data som leses linjevis, et tegn om gangen Teksten kan komme fra lesing av en fil eller en pipeline fra en annen Linux-kommando sed leser gjennom teksten bare en gang: Effektivt (men begrenset funksjonalitet) Brukes ofte til vedlikehold av store menger med strukturerte tekstfiler, f.eks. websider i HTML
sed: Enkel bruk sed leser i utgangspunktet fra standard input og skriver til standard output Enkle redigeringskommandoer kan angis direkte på kommandolinjen: Bytter strengen Jan med Beathe: sed s/jan/beathe/ Bytter Christian med en raring, legger inn en ny linje med teksten (tidligere studieleder) hvis en linje inneholder Robert: sed e s/christian/"en raring"/ e '/Robert/ a\ (tidligere studieleder)' sed-kommandoer kan være relativt kryptiske, syntaks og tenkemåte er ikke for sarte sjeler...
sed: Typisk bruk sed f kommandofil < inputfil > outputfil Teksten som skal redigeres leses fra inputfil Ferdig redigert tekst skrives til outputfil kommandofil inneholder redigeringskommandoene som sed skal utføre på linjene som leses: Mest brukte redigeringskommando er s - substitute Hensiktsmessig å lagre mer komplekse redigeringsrutiner i en egen kommandofil, og endre denne ved behov Lager shellprogram for å håndtere mange filer med sed For (mye mer) om sed og redigeringskommandoene se: sed introduction and tutorial man sed
sed: Eksempel på bruk i shellscript fixdir: Shellprogram som går gjennom alle HTML-filer i en gitt katalog Redigerer hver fil med sed sed_input: Fil med sed-kommandoer som kjøres for hver HTML-fil som fixdir behandler sed_input må ligge i samme katalog som HTML-filene Det er viktig å teste ut scripts som bruker sed for feil, før de settes i produksjon på store datamengder...
cut: Utvalg av kolonner med data Plukker ut deler av linjer i tekstlig input og skriver disse til standard output eller til fil Delene som skal tas ut velges som: Enten faste kolonner angitt med tegnposisjon, eller Felt på linjene mellom skilletegn (i databaser etc.) Brukes ofte til å hente ut bestemte verdier fra system- og brukerinformasjon i Linux cut er lettvint å formulere eksamensoppgaver med...
cut: Opsjoner c characters Plukk ut faste tegnposisjoner f fields Plukk ut felter mellom skilletegn d delimiter Angi skilletegnet (default er TAB) s only-delimiter Ikke skriv ut linjer uten skilletegn complement Velg delen av linjen som ikke er angitt output delimiter=string Bruk STRING som skilletegn i output
cut: Eksempler cut c3,5 Plukk 3. og 5. tegn på hver linje cut c2 8 Fra og med 2. til og med 8. tegn cut c 5 Fra start av linje til og med 5. tegn cut c8 Fra og med 8. tegn til slutten av hver linje cut f2 cut f3 5 cut c 2,8 2. felt på linjen 3., 4. og 5. felt på linjen 1. og 2. tegn, og fra og med 8 til slutten cut complement c 2,8 Samme som cut c3,4,5,6,7
cut: Hente ut brukerinformasjon Brukernavn og fullt navn for alle brukere: ypcat passwd cut d: f1,5 Hvor mange heter Ole?: ypcat passwd cut d: f5 grep w\ [Oo]le wc l PID og navn for alle prosessene til en bruker: ps u janh tr s ' ' ' ' cut\ d' ' f2,5 Navn og innloggingstidspunkt for alle som er logget på systemet: who tr s ' ' ' ' cut d' ' f1,4
cut: Hente ut systeminformasjon Hvor mye RAM er det på maskinen?: free grep Mem tr s ' ' ' ' cut d' ' f2 Hvor mange Kbytes med diskplass er det i hele filsystemet? df total grep ^total tr s ' ' ' ' cut\ d' ' f2 Hva slags CPU er installert?: cat /proc/cpuinfo grep name cut d: f2 uniq Hva er Mac-adressen til nettverkskortet?: ifconfig eth0 grep HWaddr cut d' ' f11 Hvilken nettverkstjeneste bruker en bestemt port?: egrep w <portnr> /etc/services cut f1 uniq
Funksjoner i shellscript Kode kan gjenbrukes i shell ved å legge den i en shellfunksjon Syntaks: navn () { } kommando kommando... Parametre som gis refereres til lokalt i funksjonen som $1 $2 $3..., på samme måte som i shellprogrammet Vanlig å legge egne shellfunksjoner i innloggingsfilen.profile i Bourne shell
Funksjoner; Eksempler med cut kl () { echo n "Klokken er " date cut d' ' f4 } cpu () { cat /proc/cpuinfo grep name cut d:\ f2 uniq tr s ' ' ' ' } portsrv () { egrep w $1 /etc/services cut f1 uniq }
diff: Sammenligning av tekst Sammenligner to tekstfiler linje for linje Finner linjer som er forskjellige i de to filene Produserer output med redigeringskommandoer som kan brukes av verktøyet patch for å gjøre filene like diff og patch kan brukes i automatisk oppdatering av programvare og tekstlig innhold Varianter og beslektede program: sdiff diff3 cmp comm «side-by-side diff» Sammenligner tre filer Sammenligner to filer byte for byte Sammenligner sorterte filer