¿Cómo agregar datos al búfer en el script de shell?

Me gustaría hacer el siguiente uso del script de shell: (para simplificar, uso los mismos datos para INPUT. En el caso real, los datos cambian con la label de bucle jj)

#!/bin/sh for jj in `seq 100`; do cat INPUT.file >> OUTPUT.file done 

Sin embargo, esto es muy ineficaz ya que abrir y cerrar el file están en el ciclo. Cuando el tamaño del file INPUT.file es grande, este código será muy lento. Así que me pregunto si hay una manera de tener / crear un búfer como crear una variable preasignada en C.

Gracias a la respuesta de Stéphane Chazelas a "¿Por qué hay tanta diferencia en el time de ejecución de eco y gato?" , la respuesta de muru puede mejorarse un poco llamando a cat solo una vez (sin embargo, esta cantidad "pequeña" puede ser mucho para big data y numerosas repeticiones de bucle, en mi sistema, este script toma ~ 75% de time en el ciclo) teniendo secuencias de commands):

 #!/bin/sh yes INPUT.file | head -100 | xargs cat >> OUTPUT.file 

Considere networkingirigir el bucle mismo:

 #!/bin/sh for jj in seq 100; do cat INPUT.file done >> OUTPUT.file 

Si la velocidad es su principal preocupación, entonces puede encontrar que el cat no es lo suficientemente rápido en esta tarea. Es posible que desee escribir los files constituyentes en la salida en paralelo.

Cogí una versión rápida de un cat paralelo con las siguientes advertencias:

  1. todos los files de input deben ser files regulares (para saber el tamaño por adelantado).
  2. no escriba ni trunque los files de input mientras se ejecuta fcat
  3. el file de salida ya no existe (para evitar crashs, y también para evitar perder time leyendo lo que vamos a sobrescribir).

Obviamente, esta es una testing rápida de concepto, por lo que podría hacerse más robusta, pero aquí está la idea:

fcat.c:

 #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> struct in_fd { int fd; int err; off_t start; struct stat s; }; int main(int argc, char**argv) { char *outfile = argv[--argc]; if (argc < 2) { fprintf(stderr, "Usage: %s INFILE... OUTFILE\n", argv[0]); return 1; } struct in_fd *infiles = calloc(argc, sizeof *infiles); #pragma omp parallel for for (int i = 1; i < argc; ++i) { struct in_fd *const input = infiles + i; char const *const filename = argv[i]; input->err = 0; if ((input->fd = open(filename, O_RDONLY)) < 0) { perror(filename); input->err = errno; continue; } if (fstat(input->fd, &input->s)) { perror(filename); input->err = errno; continue; } if (!S_ISREG(input->s.st_mode)) { fprintf(stderr, "%s: not a regular file\n", filename); input->err = EINVAL; continue; } } off_t total = 0; for (int i = 1; i < argc; ++i) { if (infiles[i].err) return EXIT_FAILURE; infiles[i].start = total; total += infiles[i].s.st_size; } int out_fd = open(outfile, O_RDWR | O_CREAT | O_EXCL, 0666); if (out_fd < 1) { perror(outfile); return 1; } if (ftruncate(out_fd, total)) { perror(outfile); return 1; } /* On Linux, you might wish to add MAP_HUGETLB */ char *out_mem = mmap(NULL, total, PROT_WRITE, MAP_SHARED, out_fd, 0); if (out_mem == MAP_FAILED) { perror(outfile); return 1; } #pragma omp parallel for for (int i = 1; i < argc; ++i) { struct in_fd *const input = infiles + i; char *p = out_mem + input->start; char *end = p + input->s.st_size; input->err = 0; while (p < end) { int r = read(input->fd, p, end-p); if (r < 0) { if (errno != EINTR) { perror(argv[i]); input->err = errno; break; } } else { p += r; } } close(infiles->fd); } if (munmap(out_mem, total)) { perror(outfile); } for (int i = 1; i < argc; ++i) { if (infiles[i].err) { unlink(outfile); return EXIT_FAILURE; } } return EXIT_SUCCESS; } 

Makefile:

 CFLAGS += -Wall -Wextra CFLAGS += -std=c99 -D_GNU_SOURCE CFLAGS += -g -O2 CFLAGS += -fopenmp all: fcat .PHONY:all 

Mis resultados de time con 12 hilos muestran times transcurridos de 0.2 segundos en comparación con 2.3 segundos para cat (mediana de tres carreras cada uno, con memory caching caliente, en 48 files que sumn 138M).