Comment diviser un gros fichier texte en petits fichiers avec le même nombre de lignes?

j'ai un gros fichier texte (par nombre de lignes) que j'aimerais partager en petits fichiers, aussi par nombre de lignes. Donc, si mon fichier a environ 2m de lignes, je voudrais le diviser en 10 fichiers qui contiennent 200k de lignes, ou 100 fichiers qui contiennent 20k de lignes (plus un fichier avec le reste; être également divisible n'a pas d'importance).

je pourrais le faire assez facilement en Python mais je me demande s'il n'y a pas un moyen ninja de le faire en utilisant bash et unix utils (par opposition aux lignes de bouclage et de comptage / partitionnement à la main).

370

10 réponses

avez-vous regardé le split command?

$ 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 ceci:

split -l 200000 filename

qui va créer des fichiers chacun avec 200000 lignes nommées xaa xab xac ...

une autre option, divisée par la taille du fichier de sortie (divise encore sur les pauses de ligne):

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

crée des fichiers comme output_prefix01 output_prefix02 output_prefix03 ... de taille max 20 mégaoctets chacun.

643
répondu Mark Byers 2018-05-30 11:10:22

et la commande split ?

split -l 200000 mybigfile.txt
57
répondu Robert Christie 2013-07-19 07:18:04

Oui, il y a une commande split . Il divisera un fichier en lignes ou en 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.
29
répondu Dave Kirby 2018-07-16 11:16:22

utiliser split

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

Syntax split [options] [INPUT [PREFIX]]

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

12
répondu zmbush 2013-07-19 07:18:14

utiliser:

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

ici, 1 et 100 sont les numéros de ligne que vous allez capturer dans output.txt .

12
répondu Harshwardhan 2016-04-27 16:39:45

vous pouvez également utiliser awk

awk -vc=1 'NR%200000==0{++c}{print "151900920" > c".txt"}' largefile
8
répondu ghostdog74 2010-01-07 01:03:23

diviser le fichier "fichier.txt "dans les fichiers de 10000 lignes:

split -l 10000 file.txt
7
répondu ialqwaiz 2018-02-27 09:11:14

dans le cas où vous voulez simplement diviser par x le nombre de lignes de chaque dossier, les asnwers donnés environ split sont OK. Mais, je suis curieux de voir que personne n'a prêté attention aux exigences:

  • "sans devoir les Compter" - > en utilisant wc + coupe
  • "avoir le reste dans des fichiers" -> split n'par défaut

je ne peux pas le faire sans "wc + coupe", mais je suis sur que:

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

cela peut être facilement ajouté à vos fonctions bashrc de sorte que vous pouvez simplement l'invoquer en passant le nom du fichier et des morceaux:

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

dans le cas où vous voulez juste x morceaux sans reste dans le fichier supplémentaire, il suffit d'adapter la formule pour la somme (Morceaux - 1) sur chaque fichier. J'utilise cette approche parce que d'habitude je veux juste x nombre de fichiers plutôt que x lignes par fichier:

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

vous pouvez ajouter cela à un script et l'appeler votre "voie ninja", parce que si rien ne correspond à vos besoins, vous pouvez le construire: -)

5
répondu erm3nda 2018-08-06 07:46:18

split (tiré de GNU coreutils, depuis version 8.8 de 2010-12-22 ) inclut le paramètre suivant:

-n, --number=CHUNKS     generate CHUNKS output files; see explanation below

CHUNKS may be:
  N       split into N files based on size of input
  K/N     output Kth of N to stdout
  l/N     split into N files without splitting lines/records
  l/K/N   output Kth of N to stdout without splitting lines/records
  r/N     like 'l' but use round robin distribution
  r/K/N   likewise but only output Kth of N to stdout

ainsi, split -n 4 input output. générera quatre fichiers ( output.a{a,b,c,d} ) avec le même nombre d'octets, mais les lignes peuvent être brisées au milieu.

si nous voulons préserver les lignes complètes (c'est-à-dire séparées par des lignes), alors cela devrait fonctionner:

split -n l/4 input output.

réponse connexe: https://stackoverflow.com/a/19031247

3
répondu Denilson Sá Maia 2018-05-31 10:40:23

HDFS getmerge fichier de petite taille et versé dans la taille de la propriété.

cette méthode causera un bris de ligne

split-B 125m compact.fichier -d-3 compact_prefix

j'ai essayé de getmerge et divisé en environ 128MB chaque dossier.

divisé en 128m ,le juge sizeunit est M ou G ,s'il vous plaît tester avant utilisation.

begainsize=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print }' `
sizeunit=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print }' `
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}
0
répondu Matiji66 2017-11-08 07:43:09