( TCH | 2020. 02. 09., v – 00:35 )

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,396s
De gondolom ez az fs-cache miatt van így. Valami retroplatformon biztos nagyobb lenne a különbség. :P