Kösz az
awk gyorstalpalót. Majd lehet, hogy egyszer jobban belemélyedek.
A mellékelt C programmal csak egy baj van, hogy a gets() a stdin-ről olvas be, azaz ahhoz, hogy ez a program bármit csináljon be kell pipe-olni neki az ASCII-artot, tehát nem standalone; ahhoz akkor fgets() kell, tehát a fájlkezelést nem lehet megúszni. Az előre a veremben allokált buffer persze a malloc()-ot feleslegessé teszi, de hát csak gyorsan elővettem a saját fájlberántómat...
Szóval, ha kiegészítjük a C példád, hogy a paramétereket is lekezelje, meg ne csak a hosszát nézze a sornak, hanem copyzza ki, amit kell (BTW copy, írtad a substr() függvényt; na az C-ben nincs, csak C++-ban: a string ősosztály egyik metódusa, meg amúgy is, azzal nem sokra megyünk, mert a terminál bal oldalán kell "lebegtetni" a kicopyzott oszlopokat), akkor ezt kapjuk:#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#define SZ_LINEBUF 4096
int main(int argc, char *argv[])
{
FILE *f;
char buf[SZ_LINEBUF], col, row, start, stop, c;
bool copy;
if (argc != 4)
{
fprintf(stderr, "Usage: getcols <file> <start> <stop>\n");
return 0;
}
start = strtol(argv[2], NULL, 10);
if (errno != 0)
{
fprintf(stderr, "Erroneous start column: %s\n", argv[2]);
return 3;
}
stop = strtol(argv[3], NULL, 10);
if (errno != 0)
{
fprintf(stderr, "Erroneous stop column: %s\n", argv[3]);
return 4;
}
f = fopen(argv[1], "rb");
if (f == NULL)
{
fprintf(stderr, "Cannot open file: %s\n", argv[1]);
return 1;
}
row = 0;
while (!feof(f))
{
fgets(buf, SZ_LINEBUF, f);
col = 0;
copy = false;
while ((c = buf[col]) != 0)
{
if ((col == start) && (!copy))
{
copy = true;
}
if (copy)
{
fprintf(stdout, "\033[%d;%dH%c", row, col - start, c);
}
if ((col == stop) && (copy))
{
copy = false;
}
++col;
}
++row;
}
fclose(f);
}Ez 60 sor a másik felállás 100 sora helyett, szóval az "Ezzel 2/3 program ki is van dobva." az inkább jó 1/3-nak (pontosabban: 40%-nak). :P A bináris mérete is 10k-ról 6k-ra ment össze. Amitől megszabadultunk: a berántós függvény, a malloc() és lekezelése, valamint a sortörések külön kezelése (fgets() itt intézi helyettünk); szóval annyira azért nem volt bloated az a C program, amit adtam. :P
Sebességben kb. semmi különbség nincs a kettő között; pár tízezreléknyi különbséget lehet csak mérni az egyben beolvasós javára:root@Csabi:~# time for i in {1..50000}; do getcols_b asciiart.txt 30 60 >/dev/null; done
real 2m0,616s
user 0m3,072s
sys 0m31,368s
root@Csabi:~# time for i in {1..50000}; do getcols asciiart.txt 30 60 >/dev/null; done
real 2m0,598s
user 0m2,956s
sys 0m31,396sDe gondolom ez az fs-cache miatt van így. Valami retroplatformon biztos nagyobb lenne a különbség. :P