tipos texto formatos extensiones ejemplos documento definicion caracteristicas archivos batch-file split command text-files lines

batch-file - extensiones - tipos de formatos de texto



Divida el archivo de texto en un archivo de texto múltiple más pequeño usando la línea de comando (9)

Tengo varios archivos de texto con aproximadamente 100,000 líneas y quiero dividirlos en archivos de texto más pequeños de 5000 líneas cada uno.

Solía:

split -l 5000 filename.txt

Eso crea archivos:

xaa xab aac xad xbe aaf

archivos sin extensiones Solo quiero llamarlos algo así como:

file01.txt file02.txt file03.txt file04.txt

o si eso no es posible, solo quiero que tengan la extensión ".txt".


¡Aquí hay uno en c # que no se queda sin memoria cuando se divide en trozos grandes! Necesitaba dividir el archivo de 95M en 10M x archivos de línea.

var fileSuffix = 0; int lines = 0; Stream fstream = File.OpenWrite($"{filename}.{(++fileSuffix)}"); StreamWriter sw = new StreamWriter(fstream); using (var file = File.OpenRead(filename)) using (var reader = new StreamReader(file)) { while (!reader.EndOfStream) { sw.WriteLine(reader.ReadLine()); lines++; if (lines >= 10000000) { sw.Close(); fstream.Close(); lines = 0; fstream = File.OpenWrite($"{filename}.{(++fileSuffix)}"); sw = new StreamWriter(fstream); } } } sw.Close(); fstream.Close();


Aquí hay un ejemplo en C # (porque eso es lo que estaba buscando). Necesitaba dividir un archivo csv de 23 GB con alrededor de 175 millones de líneas para poder ver los archivos. Lo dividí en archivos de un millón de filas cada uno. Este código lo hizo en aproximadamente 5 minutos en mi máquina:

var list = new List<string>(); var fileSuffix = 0; using (var file = File.OpenRead(@"D:/Temp/file.csv")) using (var reader = new StreamReader(file)) { while (!reader.EndOfStream) { list.Add(reader.ReadLine()); if (list.Count >= 1000000) { File.WriteAllLines(@"D:/Temp/split" + (++fileSuffix) + ".csv", list); list = new List<string>(); } } } File.WriteAllLines(@"D:/Temp/split" + (++fileSuffix) + ".csv", list);


Este programa de línea de comandos de Windows "Splitter de archivos" funciona muy bien: https://github.com/dubasdey/File-Splitter

Es de código abierto, simple, documentado, probado y funcionó para mí.

Ejemplo:

fsplit -split 50 mb mylargefile.txt


He creado un programa simple para esto y su pregunta me ayudó a completar la solución ... Agregué una característica más y algunas configuraciones. En caso de que quiera agregar un carácter / cadena específico después de cada pocas líneas (configurable). Por favor revisa las notas. He agregado los archivos de código: https://github.com/mohitsharma779/FileSplit


La sintaxis se ve así:

$ split [OPTION] [INPUT [PREFIX]]

donde el prefijo es PREFIXaa, PREFIXab, ...

Simplemente use uno adecuado y listo o simplemente use mv para cambiar el nombre. Creo que $ mv * *.txt debería funcionar, pero pruébelo primero a menor escala.

:)


Mi requerimiento era un poco diferente. A menudo trabajo con archivos delimitados por comas y delimitados por tabulaciones ASCII donde una sola línea es un único registro de datos. Y son realmente grandes, así que necesito dividirlos en partes manejables (conservando al mismo tiempo la fila del encabezado).

Por lo tanto, volví a mi método clásico VBScript y mezclé un pequeño script .vbs que se puede ejecutar en cualquier computadora con Windows (se ejecuta automáticamente con el motor de script WScript.exe en la ventana).

El beneficio de este método es que utiliza Text Streams, por lo que los datos subyacentes no se cargan en la memoria (o, al menos, no todos a la vez). El resultado es que es excepcionalmente rápido y no necesita mucha memoria para funcionar. El archivo de prueba que acabo de dividir con esta secuencia de comandos en mi i7 era de aproximadamente 1 GB en tamaño de archivo, tenía alrededor de 12 millones de líneas de prueba y 25 archivos de partes (cada uno con aproximadamente 500k líneas cada uno) - el procesamiento duró 2 minutos y no lo hizo No utilice más de 3 MB de memoria utilizada en cualquier punto.

La advertencia aquí es que se basa en que el archivo de texto tiene "líneas" (lo que significa que cada registro está delimitado con un CRLF) ya que el objeto Text Stream usa la función "ReadLine" para procesar una sola línea a la vez. Pero, si trabajas con archivos TSV o CSV, es perfecto.

Option Explicit Private Const INPUT_TEXT_FILE = "c:/bigtextfile.txt" ''The full path to the big file Private Const REPEAT_HEADER_ROW = True ''Set to True to duplicate the header row in each part file Private Const LINES_PER_PART = 500000 ''The number of lines per part file Dim oFileSystem, oInputFile, oOutputFile, iOutputFile, iLineCounter, sHeaderLine, sLine, sFileExt, sStart sStart = Now() sFileExt = Right(INPUT_TEXT_FILE,Len(INPUT_TEXT_FILE)-InstrRev(INPUT_TEXT_FILE,".")+1) iLineCounter = 0 iOutputFile = 1 Set oFileSystem = CreateObject("Scripting.FileSystemObject") Set oInputFile = oFileSystem.OpenTextFile(INPUT_TEXT_FILE, 1, False) Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True) If REPEAT_HEADER_ROW Then iLineCounter = 1 sHeaderLine = oInputFile.ReadLine() Call oOutputFile.WriteLine(sHeaderLine) End If Do While Not oInputFile.AtEndOfStream sLine = oInputFile.ReadLine() Call oOutputFile.WriteLine(sLine) iLineCounter = iLineCounter + 1 If iLineCounter Mod LINES_PER_PART = 0 Then iOutputFile = iOutputFile + 1 Call oOutputFile.Close() Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True) If REPEAT_HEADER_ROW Then Call oOutputFile.WriteLine(sHeaderLine) End If End If Loop Call oInputFile.Close() Call oOutputFile.Close() Set oFileSystem = Nothing Call MsgBox("Done" & vbCrLf & "Lines Processed:" & iLineCounter & vbCrLf & "Part Files: " & iOutputFile & vbCrLf & "Start Time: " & sStart & vbCrLf & "Finish Time: " & Now())


Sé que la pregunta fue hecha hace mucho tiempo, pero estoy sorprendido de que nadie haya dado la respuesta de Unix más directa:

split -l 5000 -d --additional-suffix=.txt $FileName file

  • -l 5000 : divide el archivo en archivos de 5.000 líneas cada uno.
  • -d : sufijo numérico. Esto hará que el sufijo vaya de 00 a 99 de forma predeterminada en lugar de aa a zz.
  • --additional-suffix : le permite especificar el sufijo, aquí la extensión
  • $FileName : nombre del archivo a dividir.
  • file : prefijo para agregar a los archivos resultantes.

Como siempre, revisa el man split para más detalles.

Para Mac, la versión predeterminada de la split aparentemente está embotada. Puede instalar la versión de GNU con el siguiente comando. ( vea esta pregunta para más utilidades de GNU )

brew install coreutils

y luego puede ejecutar el comando anterior reemplazando split con gsplit . Echa un vistazo a man gsplit para más detalles.


Tal vez puedas hacer algo como esto con awk

awk ''{outfile=sprintf("file%02d.txt",NR/5000+1);print > outfile}'' yourfile

Básicamente, calcula el nombre del archivo de salida tomando el número de registro (NR) y dividiéndolo por 5000, agregando 1, tomando el número entero y cero relleno en 2 lugares.

De manera predeterminada, awk imprime todo el registro de entrada cuando no especifica nada más. Por lo tanto, print > outfile escribe todo el registro de entrada en el archivo de salida.

A medida que se ejecuta en Windows, no puede usar comillas simples porque no le gusta. Creo que debes poner el script en un archivo y luego decirle a awk que use el archivo, algo como esto:

awk -f script.awk yourfile

y script.awk contendrá el script de esta manera:

{outfile=sprintf("file%02d.txt",NR/5000+1);print > outfile}

O bien, puede funcionar si haces esto:

awk "{outfile=sprintf(/"file%02d.txt/",NR/5000+1);print > outfile}" yourfile


@ECHO OFF SETLOCAL SET "sourcedir=U:/sourcedir" SET /a fcount=100 SET /a llimit=5000 SET /a lcount=%llimit% FOR /f "usebackqdelims=" %%a IN ("%sourcedir%/q25249516.txt") DO ( CALL :select FOR /f "tokens=1*delims==" %%b IN (''set dfile'') DO IF /i "%%b"=="dfile" >>"%%c" ECHO(%%a ) GOTO :EOF :select SET /a lcount+=1 IF %lcount% lss %llimit% GOTO :EOF SET /a lcount=0 SET /a fcount+=1 SET "dfile=%sourcedir%/file%fcount:~-2%.txt" GOTO :EOF

Aquí hay un lote de Windows nativo que debería realizar la tarea.

Ahora no diré que será rápido (menos de 2 minutos por cada archivo de salida de 5Kline) o que será inmune a los caracteres sensibles a los lotes. Realmente depende de las características de tus datos objetivo.

q25249516.txt un archivo llamado q25249516.txt contiene 100Klines de datos para mi prueba.

Versión revisada más rápida

movimiento rápido del ojo

@ECHO OFF SETLOCAL SET "sourcedir=U:/sourcedir" SET /a fcount=199 SET /a llimit=5000 SET /a lcount=%llimit% FOR /f "usebackqdelims=" %%a IN ("%sourcedir%/q25249516.txt") DO ( CALL :select >>"%sourcedir%/file$$.txt" ECHO(%%a ) SET /a lcount=%llimit% :select SET /a lcount+=1 IF %lcount% lss %llimit% GOTO :EOF SET /a lcount=0 SET /a fcount+=1 MOVE /y "%sourcedir%/file$$.txt" "%sourcedir%/file%fcount:~-2%.txt" >NUL 2>nul GOTO :EOF

Tenga en cuenta que utilicé llimit de 50000 para probar. llimit los primeros números de archivo si llimit * 100 es mayor que el número de líneas en el archivo ( fcount configurando fcount en 1999 y use ~3 en lugar de ~2 en la línea de cambio de nombre de archivo).