Unix - Tall og Tekst!


Hva du finner på denne siden!

Når jeg tenker på editering av Tekst og Tall, tenker jeg ikke bare på å skrive inn tekst i en editor, men like mye på hvordan man kan editere tekst uten å gå inn i en editor. På denne siden vil jeg gi tips for bruk av programm som vi, sed, awk, grep, sort, perl,.... Listen blir sikkert lengre med tiden! Basiskunnskap for hvordan disse programmene fungerer må leseren skaffe seg selv!


Gawk!

Det første tipset beskriver hvordan man kan benytte gawk til å summere en rekke tall. Anta at du har et program som spytter ut mange linjer med data. i disse linjene forekommer det tall som du vil summere, og skrive ut. De forekommer (i første omgang) på samme sted i hver linje, hvor samme sted betyr i samme kollonne, sett fra et awk-program, vi kaller denne for kollonne i. Programmet vårt heter app. Kode-biten ser slik ut:


app | gawk '{print $i; SUM += $i;} END {print SUM;}' | sort -n | l

Dette skriver ut alle tallene, og summen av dem, i numerisk ordnet rekkefølge, det minste tallet først og det største til slutt. Om du ønsker det, kan variabelen SUM initialiseres ved å legge til -v SUM=<value> først på linjen. Hvis ikke variabelen initialiseres slik, settes den pr. default til 0

Min gode venn Ola kom med et fint tips for å fjerne pakker som står som 'deinstall' i et Debian system:

dpkg --get-selections | awk '/deinstall/ {system("dpkg --purge "$1"") }'
Greia her er at dersom man fjerner en pakke i debian uten å benytte 'purge' blir konfigurasjonsfiler liggende igjen. For å slette disse helt kan nevnte kommando benyttes. Takk til Ola Skavhaug som lagde denne!

Cut!

Det neste tipset beskriver hvordan man kan hente ut vilkårlige deler av en linje tekst. Vilkårlig er kanskje å ta litt hardt i, men det jeg tenker på er å benytte kommandoen cut til å hente ut deler av en linje. Dette er et program som gjør akkurat det en skulle tro fra navnet, det kutter hver linje i input, etter gitte regler. Reglene er enkle:

  • Med -b kan man angi hvilke bit du vil ha, for eksempel -b 1,3,5 eller -b 10-15. Det første eksemplet gir tegnene i posisjon 1,3 og 5, mens vi i det siste tilfellet får tegnene fra posisjon 10 til 15.
  • Med -d kan man angi et skille tegn, som deler linjen opp i felter, dette tilsvarer hvordan awk arbeider. -d= vil dele opp linjen ved likhetstegnet. Deretter kan vi benytte -f# for å hente ut felt nummer #, første felt er nummer 1.

Et eksempel på bruk av kommandoen kan være:

cat fil | cut -d= -f2 >|ny.fil

Noen fordeler og ulemper: Kommandoen er rask, det er hovedfordelen, hvis det passer nøyaktig til ditt behov. Ulempene er først og fremst at kommandoen har et veldig enkelt og begrenset interface. Man kan bare angi en -f eller en -b opsjon. I tillegg kan man angi -d opsjonen. Se ellers man-siden til kommandoen.


Sed!

Dette er et program som kan benyttes til det meste, og jeg er ingen "guru" på feltet, men litt kommer det nok etterhvert. Sed brukes til såkalt batch-editering av tekst, det vil si editering utenfor en vanlig editor, direkte fra kommando-linjen. Dette har den fordelen at det er svært raskt, hvis man kjenner kommandoene. Det første tipset jeg presenterer her beskriver hvordan man kan bytte om rekkefølgen på deler av en linje. La oss anta at vi har teksten "nyttig er sed". Denne ønsker vi å endre til "sed er nyttig". Det kan vi gjøre slik:


echo "nyttig er sed" | sed s'/\(.*\)\(er\)\(.*\)/\3 \2 \1/'

Vi benytter her tilbake-refereringsmekanismen i sed!

Hvis du ønsker mer informasjon om Sed, kan du se på siden The seder's grab-bag


tr

Noen ganger kan tr brukes som et ok alternativ til sed. tr står for translate, og kan oversette et gitt sett av tegn i inputdata til nye tegn. Syntax er veldig enkel: tr inchars outchars. For hver gang et tegn angitt i inchars opptrer i input data, byttes tegnet ut med tilsvarende tegn angitt i outchars. Det som angis i inchars og outchars er enten vanlige tegn, meta-tegn eller spesial-uttrykk tilsvarende de som brukes av grep. Mer om dette siden om jeg får tid og lyst! Dersom det er færre tegn angitt i outchars enn i inchars, vil siste tegn bli benyttet for "resten": tr abc cde vil erstatte a med c, b med d, etc, mens tr abc df vil erstatte a med d og både b og c med f.

Anta for eksempel at du har en linje med ting på som er adskilt av et eller annet tegn, og at du ønsker å splitte dette opp slik at hver ting kommer på egen linje. Det kan for eksempel gjøres slik:

echo $PATH | tr : \\n
Merk dobbel slash før n, siden shellet spiser opp den ene. Alternativt kan quote (') brukes.
Perl!

Det beste som har hendt verden når det gjelder noe ellers så bagatellmessig som programmering, er at språket perl så dagens lys, for ikke å si datamaskines strøm(?). Dette språket er svært fleksibelt og effektivt til sitt bruk. Dessuten kan man finne sin egen personlige stil i språket, fordi man kan formulere nesten alt mulig på mange forskjellige måter. Jeg er selv en nybegynner i Perl, men vil allikevel skrive ned en del tips her, både av ting som jeg selv finner på, og annet som jeg leser på news-grupper, som jeg vil spare for senere bruk. Jeg forutsetter at leseren har litt greie på perl fra før. I motsatt fall kan man lete i bokmerkene mine etter passende referanser.

Det første tipset jeg vil gi her, er bruk av funksjonen split. Anta at du har en streng slik:

Hei | Jeg | Heter | Olaf

som du vil splitte opp ved |, og samtidig fjerne alle blanke tegn rundt ordene. Anta videre at teksten er lagret i default-variabelen $_. Da kan man ganske enkelt si dette:
@parts = split /\s*\|\s*/;

Dette deler ved |. Dessuten vil \s* rundt dele-tegnet, føre til at de blanke tegnene forsvinner. (Husk at ved bruk av split vil "deletegnet" (som her er blanke*|+blanke) bli fjernet. Resultatet vil bli lagret i arrayet @parts som man kan arbeide videre med.

Alle vet at det er mer enn en måte å gjøre ting på i perl. Derfor skal du ta en titt på den følgende kode-snutten:

sub foo { shift; $_ and print or print "foo"; }; 
sub bar { 1; };
foo if bar;
bar and foo;
foo, bar;
if ( bar() ) { foo(); }
Det er en av de fire måtene å si dette på som ikke hører hjemme her, men det får være en oppgave for deg min kjære leser å finne ut hvilken det dreier seg om. Hovedpoenget er at vi kan skrive logikken begge veier i Perl. Et par eksempler til som er litt morsomme:
do { foo and bar } if bar;
print for @INC;
foo for @INC;
Ok, det siste avsnittet hadde lite her å gjøre siden det ikke har med tall og tekst å gjøre, men det får stå her inntil jeg får en side som handler spesielt om Perl.

The most recent update of this page was done:10.03.2007 by Åsmund Ødegård