two new matlab file-io line-count

new - ¿Hay alguna manera en Matlab para determinar el número de líneas en un archivo sin pasar por cada línea?



new line title matlab (5)

Creo que un bucle es de hecho el mejor, todas las demás opciones hasta ahora sugerían confiar en programas externos (necesitan verificar errores, necesitan str2num, son más difíciles de depurar / ejecutar multiplataforma, etc.) o leen todo el archivo de una vez . Los bucles no son tan malos. Aquí está mi variante

function count = countLines(fname) fh = fopen(fname, ''rt''); assert(fh ~= -1, ''Could not read: %s'', fname); x = onCleanup(@() fclose(fh)); count = 0; while ischar(fgetl(fh)) count = count + 1; end end

EDITAR: Jonas señala correctamente que el ciclo anterior es muy lento. Aquí hay una versión más rápida.

function count = countLines(fname) fh = fopen(fname, ''rt''); assert(fh ~= -1, ''Could not read: %s'', fname); x = onCleanup(@() fclose(fh)); count = 0; while ~feof(fh) count = count + sum( fread( fh, 16384, ''char'' ) == char(10) ); end end

Todavía no es tan rápido como wc -l , pero tampoco es un desastre.

Obviamente, uno podría recorrer un archivo usando fgetl o una función similar e incrementar un contador, pero ¿hay alguna manera de determinar el número de líneas en un archivo sin hacer un bucle?


Encontré un buen truco here :

if (isunix) %# Linux, mac [status, result] = system( [''wc -l '', ''your_file''] ); numlines = str2num(result); elseif (ispc) %# Windows numlines = str2num( perl(''countlines.pl'', ''your_file'') ); else error(''...''); end

donde ''countlines.pl'' es una secuencia de comandos perl, que contiene

while (<>) {}; print $.,"/n";


Me gusta usar el siguiente código para exactamente esta tarea

fid = fopen(''someTextFile.txt'', ''rb''); %# Get file size. fseek(fid, 0, ''eof''); fileSize = ftell(fid); frewind(fid); %# Read the whole file. data = fread(fid, fileSize, ''uint8''); %# Count number of line-feeds and increase by one. numLines = sum(data == 10) + 1; fclose(fid);

Es bastante rápido si tiene suficiente memoria para leer todo el archivo a la vez. Debería funcionar para finales de línea de estilo Windows y Linux.

Editar: Medí el rendimiento de las respuestas proporcionadas hasta el momento. Aquí está el resultado para determinar el número de líneas de un archivo de texto que contiene 1 millón de valores dobles (un valor por línea). Promedio de 10 intentos.

Author Mean time +- standard deviation (s) ------------------------------------------------------ Rody Oldenhuis 0.3189 +- 0.0314 Edric (2) 0.3282 +- 0.0248 Mehrwolf 0.4075 +- 0.0178 Jonas 1.0813 +- 0.0665 Edric (1) 26.8825 +- 0.6790

Los más rápidos son los enfoques que usan Perl y la lectura de todo el archivo como datos binarios. No me sorprendería si Perl internamente también leyera grandes bloques del archivo a la vez en lugar de recorrerlo línea por línea (solo una suposición, no sé nada sobre Perl).

Usar un simple fgetl() -loop es por un factor de 25-75 más lento que los otros enfoques.

Editar 2: incluyó el segundo enfoque de Edric, que es mucho más rápido y a la par con la solución de Perl, diría yo.


Puede leer el archivo completo a la vez y luego contar cuántas líneas ha leído.

fid = fopen(''yourFile.ext''); allText = textscan(fid,''%s'',''delimiter'',''/n''); numberOfLines = length(allText{1}); fclose(fid)


Yo recomendaría usar una herramienta externa para esto. Por ejemplo, una aplicación llamada cloc , que puedes descargar here gratis.

En Linux, simplemente escriba cloc <repository path> y obtenga

YourPC$ cloc <directory_path> 87 text files. 81 unique files. 23 files ignored. http://cloc.sourceforge.net v 1.60 T=0.19 s (311.7 files/s, 51946.9 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- MATLAB 59 1009 1074 4993 HTML 1 0 0 23 ------------------------------------------------------------------------------- SUM: 60 1009 1074 5016 -------------------------------------------------------------------------------

También afirman que debería funcionar en Windows.