Dividir un archivo por línea y tener control sobre la extensión de archivos resultante


28

Hay un comando estándar para dividir archivos: dividir.

Por ejemplo, si quiero dividir un archivo de palabras en varios fragmentos de 10000 líneas, puedo usar:

split -dl 10000 words wrd

y generaría varios archivos de la forma wrd.01, wrd.02, etc.

Pero quiero tener una extensión específica para esos archivos; por ejemplo, quiero obtener archivos wtd.01.txt, wrd.02.txt.

¿Hay una manera de hacerlo?

Respuestas:


12

No con split, pero puede cambiarles el nombre fácilmente más tarde, o puede hacerlo en awk:

awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile

Se ve bien, pero no funciona. En su formulario, se queja de que "la expresión para la redirección` >> 'tiene un valor de cadena nulo ", y si" archivo "se" cambia "a" nombre de archivo ", genera archivos del formulario wrd. {Número de archivo}. {Número de línea} .txt (bastantes de ellos :)
Rogach

@Rogach Lo siento, no lo había probado, así que olvidé que awk no hace división entera. He probado este.
Kevin

49

Esto no estaba disponible en ese momento, pero con versiones más recientes ( ≥ 8.16) de gnu splituno puede usar el --additional-suffixinterruptor para tener control sobre la extensión resultante. De man split:

--additional-suffix=SUFFIX
              append an additional SUFFIX to file names.

así que al usar esa opción:

split -dl 10000 --additional-suffix=.txt words wrd

las piezas resultantes terminarán automáticamente en .txt:

wrd00.txt
wrd01.txt
.........

3
No funciona en mac
ericgu

2
Amo tu sarcasmo. Soy un unix n00b del mundo de Apple. Estoy usando OS X Yosemite y simplemente no quería que otros se bloqueen y se quemen como lo hice. Probé y revisé en los documentos y no tenemos este parámetro. Podría haber perdido algo. developer.apple.com/library/mac/documentation/Darwin/Reference/…
ericgu

55
@swiftshokunin: mi respuesta pertenece a gnu splitparte de gnu coreutils. También está disponible en OSX si realiza la instalación a coreutilstravés de, homebrewpero tenga en cuenta que, de manera predeterminada, en OSX, las gnuutilidades tienen gantepuesto a su nombre (por ejemplo, en gstatlugar de stat), por lo que puede invocarlo gsplit(o modificar la RUTA según la guía aquí si lo desea) para usarlo splitsobre el OSX split). HTH
don_crissti

1
Buena respuesta. en OS X, use gsplitpara que los sufijos numéricos (-d) funcionen.
Brent Faust

1
wow, no tenía idea de que hay gsplit, probablemente sea de los coreutils mencionados anteriormente y tiene un sufijo adicional. Gracias a todos por comentar esta solución :)
Łukasz Rysiak

13

Dichas tareas se gestionan mejor con el shell. Use dividir y luego escriba un bucle simple para cambiar el nombre de los archivos. P.ej

for file in wrd.*
do
    mv "$file" "$file.txt"
done

cambiaría el nombre de sus archivos wrd.01, wrd.02, etc. para que todos tengan una extensión .txt.


Eso es bastante obvio, pero rompería la concisión del script bash.
Rogach

1
La filosofía de Unix es proporcionarle un conjunto de herramientas simples que luego combina para hacer un trabajo. La "concisión de la secuencia de comandos bash" no era un requisito establecido en su pregunta.
Kyle Jones

77
PD: el split+mvcombo es más de 6 veces más rápido que awk(aproximadamente 3s frente a 18s ) para un archivo de entrada de 10 millones de líneas (75 MB) ... el texto en cada línea era su propio número de línea ... Gracias por repetirlo el "obvio" :)
Peter.O

3
PPS: Acabo de comprobar esto un poco más. La diferencia de velocidad está relacionada con la cantidad de archivos creados frente a la cantidad de formato y cálculos aritméticos que awk hace para cada línea, independientemente de la cantidad de archivos de salida ... Usando el mismo archivo de entrada que el ejemplo anterior: Cuando hay 100 veces menos archivos, split + mves 75 veces más rápido que awk: cuando hay 100 veces más archivos, split + mves 1,5 veces más rápido que awk. Entonces, para mí, este split + mvmétodo gana, sin duda. Es como consice (posiblemente más), y es más rápido que awk.
Peter.O

1
si le preocupa que tenga 5 líneas de largo, intente esto en su lugar: for file in wrd.*; do mv "$file" "$file.txt"; done:)
Tony
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.