Moni tietää, että Linuxissa on paljon tekstivirtojen käsittelyyn liittyviä työkaluohjelmia. Eräs yleinen pikku ongelma on tulostaa tekstivirran kaikki rivit paitsi ensimmäinen, koska se ensimmäinen on jonkinlainen otsikkorivi kuten ps
komennon tulosteessa:
Ongelman voi helposti ratkaista ainakin kolmella ohjelmalla. Laitetaan ensin ps -ef
komennon tuloste tiedostoon, jotta ohjelmille annettu syöte olisi aina samanlainen:
Syötetiedosto ei ole suuri:
bash
komentotulkkia varten tehty skriptitiedosto on seuraavanlainen. Koska emme tässä tapauksessa ole kiinnostuneita näkemään komentojen tulostetta terminaalillamme vaan ainoastaan ohjelmien suoritusnopeuden, me ohjaamme niiden stdout
virran /dev/null
pseudotiedostoon, jolloin tuloste menee käyttöjärjestelmän toimesta suoraan "roskikseen":
Linuxissa valmiina olevat ohjelmat ovat awk
, sed
ja tail
. skipfirst
on oma pikainen kotikutoinen C-ohjelmamme, joka on mukana vain vertailun vuoksi. Tiedän kyllä hyvin sen virheet ja että se ei ole tuotantokelpoinen. Ohjelma sopii kuitenkin testikäyttöömme ja näyttää seuraavalta:
#include <stdio.h> #include <stdlib.h> #define MAXLINELEN 4096 int main(int argc, char *argv[]) { char linebuf[MAXLINELEN]; char *infile; FILE *fp; if (argc != 2) { fprintf(stderr, "usage: skipfirst [infile]\n"); exit(EXIT_FAILURE); } infile = argv[1]; if ((fp = fopen(infile, "r")) == NULL) { fprintf(stderr, "could not open %s\n", infile); exit(EXIT_FAILURE); } (void)fgets(linebuf, sizeof(linebuf), fp); while (fgets(linebuf, sizeof(linebuf), fp)) { fputs(linebuf, stdout); } (void)fclose(fp); return 0; }
Käänsin sen komennolla:
Tehdään seuraavaksi kolme ajokertaa, joista jokainen suorittaa kunkin komennon 3000 kertaa:
awk 'NR>1'
skriptimme oli joka kerralla hitain noin 6,6 sekunnin suoritusajallaan. Sitä hieman parempi oli sed '1d'
skripti, joka oli noin sekunnin nopeampi. Komento tail -n +2
oli joka kerralla noin sekunnin nopeampi kuin sed '1d'
skripti. Oma C-ohjelmamme skipfirst
oli käytännössä yhtä nopea kuin tail -n +2
.
Onko tällä testillä mitään käytännön merkitystä? Eipä juuri, mutta jos joskus halutaan mikro-optimoida esimerkiksi jotain shelliskriptiä, joka käyttää jotain noista kolmesta ohjelmasta ensimmäisten rivien poisjättämiseen, niin nopeinta lienee käyttää tail
komentoa. Se voi olla myös aavistuksen helpommin luettavampi vaihtoehto verrattuna kahteen muuhun skriptiin. Tarkistin myös POSIX-standardista, että -n +2
notaatio on käytettävissä standardinmukaisissa tail
implementaatioissa. Eli kyseessä ei ole mikään Linux-spesifinen GNU-laajennos.