709 votes

Comment diviser un grand fichier texte en fichiers plus petits avec un nombre égal de lignes ?

J'ai un fichier texte brut de grande taille (en nombre de lignes) que j'aimerais diviser en fichiers plus petits, également en nombre de lignes. Ainsi, si mon fichier contient environ 2 millions de lignes, j'aimerais le diviser en 10 fichiers contenant 200 000 lignes, ou 100 fichiers contenant 20 000 lignes (plus un fichier contenant le reste ; le fait qu'il soit divisible à parts égales n'a pas d'importance).

Je pourrais le faire assez facilement en Python, mais je me demande s'il existe un moyen ninja de le faire en utilisant Bash et les utilitaires Unix (par opposition à la mise en boucle manuelle et au comptage/partitionnement des lignes).

3 votes

Par curiosité, une fois qu'ils sont "divisés", comment fait-on pour les "combiner" ? Quelque chose comme "cat part2 >> part1" ? Ou existe-t-il un autre utilitaire ninja ? Cela vous dérangerait-il de mettre votre question à jour ?

14 votes

Pour le remettre ensemble, cat part* > original

12 votes

Oui, "cat" est le diminutif de "concatenate". En général, apropos est utile pour trouver les commandes appropriées. Par exemple, voyez la sortie de : apropos split

1111voto

Mark Byers Points 318575

Jetez un coup d'œil à la commande split :

$ 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

Vous pourriez faire quelque chose comme ça :

split -l 200000 filename

qui créera des fichiers de 200000 lignes chacun nommés xaa xab xac ...

Une autre option, diviser par la taille du fichier de sortie (divise toujours sur les sauts de ligne) :

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

crée des fichiers comme output_prefix01 output_prefix02 output_prefix03 ... chacun d'une taille maximale de 20 mégaoctets.

27 votes

Vous pouvez également diviser un fichier par taille : split -b 200m filename (m pour mégaoctets, k pour kilooctets ou pas de suffixe pour les octets)

157 votes

Diviser par taille et s'assurer que les fichiers sont divisés sur les sauts de ligne : split -C 200m nom de fichier

2 votes

Split produit une sortie brouillée avec une entrée Unicode (UTF-16). Au moins sous Windows avec la version que j'ai.

110voto

Robert Christie Points 7323

Utilisez le divisé commandement :

split -l 200000 mybigfile.txt

50voto

Dave Kirby Points 12310

Oui, il y a un split commande. Elle divise un fichier par lignes ou par octets.

$ 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 votes

J'ai essayé georgec@ATGIS25 ~ $ split -l 100000 /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands/trc_longlands.txt mais il n'y a pas de fichiers split dans le répertoire -où est la sortie ?

1 votes

Il doit se trouver dans le même répertoire. Par exemple, si je veux diviser par 1 000 000 de lignes par fichier, faites ce qui suit : split -l 1000000 train_file train_file. et dans le même répertoire, je vais obtenir train_file.aa avec le premier million, puis trail_file.ab avec le million suivant, etc.

2 votes

@GeorgeC et vous pouvez obtenir des répertoires de sortie personnalisés avec le préfixe : split input my/dir/ .

18voto

zmbush Points 2052

Utilice split :

Divise un fichier en morceaux de taille fixe, crée des fichiers de sortie contenant des sections consécutives de INPUT (entrée standard si aucune n'est donnée ou si INPUT est `-')

Syntax split [options] [INPUT [PREFIX]]

15voto

ghostdog74 Points 86060

Vous pouvez également utiliser AWK :

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

4 votes

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

0 votes

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X