2010-01-06 42 views
314

Tengo un gran archivo de texto plano (por número de líneas) que me gustaría dividir en archivos más pequeños, también por número de líneas. Entonces, si mi archivo tiene alrededor de 2M líneas, me gustaría dividirlo en 10 archivos que contienen 200k líneas, o 100 archivos que contienen 20k líneas (más un archivo con el resto, ser igual de divisible no importa).¿Cómo dividir un archivo de texto grande en archivos más pequeños con igual cantidad de líneas?

Podría hacer esto bastante fácilmente en Python, pero me pregunto si hay algún tipo de forma ninja para hacerlo utilizando utilidades bash y unix (a diferencia de las líneas de bucle y recuento/división manual).

+1

Fuera de curiosidad, después de que son "split", ¿cómo se "combinan" ellos? Algo así como "cat part2 >> part1"? ¿O hay otra utilidad ninja? ¿Te importa actualizar tu pregunta? – dlamotte

+3

Para volver a armarlo, 'cat part *> original' –

+6

yes cat es la abreviatura de concatenar. En general, a propósito es útil para encontrar los comandos apropiados. ES DECIR. vea la salida de: apropos split – pixelbeat

Respuesta

543

¿Has mirado el comando dividir?

$ split --help 
Usage: split [OPTION] [INPUT [PREFIX]] 
Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default 
size is 1000 lines, and default PREFIX is `x'. With no INPUT, or when INPUT 
is -, read standard input. 

Mandatory arguments to long options are mandatory for short options too. 
    -a, --suffix-length=N use suffixes of length N (default 2) 
    -b, --bytes=SIZE  put SIZE bytes per output file 
    -C, --line-bytes=SIZE put at most SIZE bytes of lines per output file 
    -d, --numeric-suffixes use numeric suffixes instead of alphabetic 
    -l, --lines=NUMBER  put NUMBER lines per output file 
     --verbose   print a diagnostic to standard error just 
          before each output file is opened 
     --help  display this help and exit 
     --version output version information and exit 

Se podría hacer algo como esto:

split -l 200000 filename 

que creará archivos cada uno con 200.000 líneas nombradas xaa xab xac ...

Otra opción, dividido por el tamaño del archivo de salida (todavía escisiones en saltos de línea):

split -C 20m --numeric-suffixes input_filename output_prefix 

crea archivos como output_prefix01 output_prefix02 output_prefix03 ... cada uno de un tamaño máximo de 20 megabytes.

+13

También puede dividir un archivo por tamaño: 'split -b 200m filename' (m para megabytes, k para kilobytes o ningún sufijo para bytes) –

+108

dividido por tamaño y asegúrese de que los archivos estén divididos en saltos de línea: split-200m filename –

+2

split produce salida ilegible con entrada Unicode (UTF-16). Al menos en Windows con la versión que tengo. – Vertigo

10

uso split

dividir un archivo en trozos de tamaño fijo, crea archivos de salida que contienen secciones consecutivas de entrada (entrada estándar si no se da ninguno o INPUT es `- ')

Syntax split [options] [INPUT [PREFIX]]

http://ss64.com/bash/split.html

48

¿Y el split comando?

split -l 200000 mybigfile.txt 
25

Sí, hay un comando split. Se dividirá un archivo por líneas o bytes.

$ split --help 
Usage: split [OPTION]... [INPUT [PREFIX]] 
Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default 
size is 1000 lines, and default PREFIX is `x'. With no INPUT, or when INPUT 
is -, read standard input. 

Mandatory arguments to long options are mandatory for short options too. 
    -a, --suffix-length=N use suffixes of length N (default 2) 
    -b, --bytes=SIZE  put SIZE bytes per output file 
    -C, --line-bytes=SIZE put at most SIZE bytes of lines per output file 
    -d, --numeric-suffixes use numeric suffixes instead of alphabetic 
    -l, --lines=NUMBER  put NUMBER lines per output file 
     --verbose   print a diagnostic just before each 
          output file is opened 
     --help  display this help and exit 
     --version output version information and exit 

SIZE may have a multiplier suffix: 
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024, 
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y. 
+0

Probado georgec @ ATGIS25 ~ $ split -l 100000 /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands/trc_longlands.txt pero no hay archivos divididos en el directorio, ¿dónde está el resultado? – GeorgeC

+0

Debe estar en el mismo directorio. P.ej. si quiero dividir en 1,000,000 líneas por archivo, haga lo siguiente: 'split -l 1000000 train_file train_file' y en el mismo directorio obtendré' train_file.aa' con el primer millón, luego 'trail_file.ab' con el próximo millón, etc. – Will

+0

@GeorgeC y puede obtener directorios de salida personalizados con el prefijo: 'split input my/dir /'. –

6

también se puede usar awk

awk -vc=1 'NR%200000==0{++c}{print $0 > c".txt"}' largefile 
+0

No está mal, pero no está tan lejos de lo que hubiera hecho en Python. – danben

+2

'awk -v lines = 200000 -v fmt ="% d.txt "'{print> sprintf (fmt, 1 + int ((NR-1)/lines))}' ' –

10

Uso:

sed -n '1,100p' filename > output.txt 

Aquí, 1 y 100 son los números de línea que se va a capturar en output.txt.

+1

Me gusta esta respuesta. Corto y dulce. Gracias – ChikuMiku

4

En caso de que solo quiera dividir por x número de líneas cada archivo, las respuestas dadas sobre split son correctas. Pero tengo curiosidad de que nadie haya prestado atención a algunos requisitos por parte de Asker.

  • "Sin mayores tienen que contar con ellos" -> usando wc + cortar
  • "tener el resto en archivo extra" -> Split hace por defecto

Actualmente estoy usando ese:

split -l $(expr `wc $filename | cut -d ' ' -f3`/$chunks) $filename 

Esto se puede agregar fácilmente a sus funciones bashrc por lo que sólo puede invocar pasando nombre de archivo y trozos:

split -l $(expr `wc $1 | cut -d ' ' -f3`/$2) $1 

En caso de que desee simplemente x fragmentos sin resto en el archivo adicional, simplemente adapte la fórmula para sumarlo (fragmentos - 1) en cada archivo. Hago uso de este enfoque porque por lo general sólo quiero x número de archivos en lugar de líneas x por archivo:

split -l $(expr `wc $1 | cut -d ' ' -f3`/$2 + `expr $2 - 1`) $1 

Usted puede añadir que a un guión y decir que es su "camino ninja", porque si nada adapte a sus necesidades , usted puede construirlo :-)

0

HDFS getmerge archivo pequeño y se derramó en el tamaño de la propiedad.

Este método hará que la línea romper

dividida -b 125m compact.file -d -a 3 compact_prefix

Trato de getmerge y se dividió en aproximadamente 128 MB cada archivo.

dividido en 128m, juez sizeunit es M o G, por favor prueba antes de su uso.

begainsize=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print $1}' ` 
sizeunit=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print $2}' ` 
if [ $sizeunit = "G" ];then 
    res=$(printf "%.f" `echo "scale=5;$begainsize*8 "|bc`) 
else 
    res=$(printf "%.f" `echo "scale=5;$begainsize/128 "|bc`) # celling ref http://blog.csdn.net/naiveloafer/article/details/8783518 
fi 
echo $res 
# split into $res files with number suffix. ref http://blog.csdn.net/microzone/article/details/52839598 
compact_file_name=$compact_file"_" 
echo "compact_file_name :"$compact_file_name 
split -n l/$res $basedir/$compact_file -d -a 3 $basedir/${compact_file_name} 
2

dividir el archivo "archivo.txt" en 10000 líneas de archivos:

split -l 10000 file.txt 
Cuestiones relacionadas