8. december

Cut

Dagens kalendergavekommando er cut.

Cut er en relativt simpel kommando, der kan være nyttig når man skal bruge enkelte dele fra hver linie fra en fil eller fra noget output. Hvis man f.eks. har en fil med navne og adresser, og kun vil have alle postnumrene ud, kan man ofte gøre det med cut.

Cut tager imod en fil eller stdin, og outputtet kommer på stdout. Uden options giver cut ikke mening, man er nødt til at fortælle den, hvad man vil have "klippet". Så vi starter med at kigge på de forskellige options til cut.

Som eksempel bruger vi filen foo, der indeholder:

Anders And:Paradisæblevej 111:6666 Andeby
Lucky Luke:Mod solnedgangen:Det vilde vesten
Spirillen:Det grønne helvede:Palombia
Jens Fup:Første kompagni:Pløresøldalslejren
Tux:Pingvinkolonien:Sydpolen

  • -b står for bytes. "cut -b 4 foo" giver f.eks. den 4. byte hver linie i filen foo. Man kan også angive en range, "cut -b 3-10 foo" giver fra den 3. til den 10. byte i filen. En range på -10 giver fra starten af linien til byte nummer 10, imens 10- giver fra byte nummer ti og resten af linien.

  • -c virker tilsvarende, bortset fra at der ses på tegn og ikke på bytes. I vores eksempel giver det det samme.

  • -d bruges til at angive "delimiter", som er det tegn der adskiller felter. Felter vender vi tilbage til om et øjeblik. Hvis ikke andet angives en -d option, er delimiteren tabulator-tegnet.

  • -f betyder felt. Man angiver hvilke(t) felt(er) man man have. Felterne er adskilt af delimiteren. Hvis vi blot siger "cut -f 2 foo", får vi hele filen. Der er ingen tabulator og derfor ingen felter.
    Anvender vi derimod ":" som delimiter, får vi et ganske andet resultat: "cut -d : -f 2 foo" giver
    Paradisæblevej 111
    Mod solnedgangen
    Det grønne helvede
    Første kompagni
    Pingvinkolonien
    
    - altså det andet felt i filen, separeret med kolon'er.

  • -s betyder at vi ikke vil se de linier, der ikke indeholder nogen delimiter. "cut -f 2 -s foo" giver altså intet output.

Eksempel

Det var alt - som sagt er cut en simpel kommando. Så vi tager lige et praktisk eksempel. Jeg vil gerne se de fejlreferencer der har været på min webside i i går, ved at kigge på min httpd access_log fil.

cat /var/log/httpd/access_log \
  | cut -d' ' -f4,7,9,11 \
  | cut -c2-3,22- \
  | grep "^`date -d yesterday +"%d"` " \
  | cut -c4- \
  | grep ' 404 ' \
  | grep -v '"-"$' \
  | sort -fu
En linie fra Apache log filen har formatet
123.456.123.456 - - [07/Dec/2001:13:49:54 +0000] "GET /funstuff/caffeine.htm HTTP/1.1" \ 
404 295 "http://www.geekgirl.dk/funstuff/" "Mozilla/3.01 (compatible;)"
Outputtet fra vores kommandorække ovenfor bliver linier af formen:
/funstuff/caffeine.htm 404 "http://www.geekgirl.dk/funstuff/"
Den første cut kommando vælger mellemrum som delimiteren, og tager felt 4, 7, 9 og 11 af alle linier. Første felt vi er interesserede i er datoen (felt 4), dernæst felt 7 som er den efterspurgte fil, felt 9 som er fejlkoden og felt 11 som er den side, referencen kommer fra.
Den første cut kommando giver altså outputtet
[07/Dec/2001:13:49:54 /funstuff/caffeine.htm 404 "http://www.geekgirl.dk/funstuff/"
Den næste kommando, "cut -c2-3,22-" klipper den overflødige del af datoen fra - vi vil se tegn 2-3 (dagen), og alt fra tegn 22 og frem, hvor datoen er slut.
07 /funstuff/caffeine.htm 404 "http://www.geekgirl.dk/funstuff/"
(det antages at logfilen roteres månedligt, ellers vi jeg få beskeder fra "den 7." i andre måneder også.)

Den tredie kommando, grep, skal vi ikke lære endnu, men den returnerer kun de linier der matcher datoen fra i går.

Den sidste cut kommando, "cut -c4-", fjerner datoen fra outputtet (viser kun fra tegn 4 og frem), så vi nu kun se:

/funstuff/caffeine.htm 404 "http://www.geekgirl.dk/funstuff/"
Derefter fjernes alt hvad der ikke er 404 fejl, og alt hvad der ikke er kommet via et link fra vores egen webside, og til sidst sorterer vi og nøjes med at vise hver fejlhenvisning een gang.

For mere information om cut: Se "man cut".