web-dev-qa-db-fra.com

Comment diviser un fichier texte en plusieurs fichiers * .txt?

J'ai reçu un fichier texte file.txt (12 Mo) contenant:

something1
something2
something3
something4
(...)

Existe-t-il un moyen de scinder file.txt en 12 fichiers * .txt, par exemple file2.txt, file3.txt, file4.txt (...)?

41
Kris

Vous pouvez utiliser l'utilitaire linux bash split 

split -b 1M -d  file.txt file 

Notez que M ou MB sont acceptables mais que leur taille est différente. MB = 1000 * 1000, M = 1024 ^ 2

Si vous souhaitez séparer par lignes, vous pouvez utiliser le paramètre -l

METTRE À JOUR

a=(`wc -l yourfile`) ; lines=`echo $a/12 | bc -l` ; split -l=$lines -d  file.txt file

Une autre solution suggérée par Kirill , vous pouvez faire quelque chose comme ce qui suit

split -n l/12 file.txt

Notez que l n'est pas one, split -n a quelques options, comme N, k/N, l/k/N, r/N, r/k/N

44
CS Pei
$ split -l 100 input_file output_file

-l est le nombre de lignes dans chaque fichier. Cela va créer: 

  • output_fileaa
  • fichier_sortie
  • sortie_fileac
  • sortie_filead
  • ....
53
amruta takawale

La réponse de John ne produira pas de fichiers .txt comme le veut le PO. Utilisation:

split -b=1M -d  file.txt file --additional-suffix=.txt
12
schoon

En utilisant bash:

readarray -t LINES < file.txt
COUNT=${#LINES[@]}
for I in "${!LINES[@]}"; do
    INDEX=$(( (I * 12 - 1) / COUNT + 1 ))
    echo "${LINES[I]}" >> "file${INDEX}.txt"
done

Utilisation de awk:

awk '{
    a[NR] = $0
}
END {
    for (i = 1; i in a; ++i) {
        x = (i * 12 - 1) / NR + 1
        sub(/\..*$/, "", x)
        print a[i] > "file" x ".txt"
    }
}' file.txt

Contrairement à split, celui-ci s'assure que le nombre de lignes est le plus égal.

1
konsolebox

Indépendamment de ce qui est dit ci-dessus, sur mon Ubuntu 16, je devais faire:

> split -b 10M -d  system.log system_split.log 

Veuillez noter l'espace entre -b et la valeur

1
Nicolas D

Je suis d'accord avec @CS Pei, mais cela n'a pas fonctionné pour moi:

split -b=1M -d file.txt file

... comme le = après le -b l'a jeté. Au lieu de cela, je l'ai simplement supprimé et je n'ai laissé aucun espace entre elle et la variable, et j'ai utilisé "m" minuscule:

split -b1m -d file.txt file

Et pour ajouter ".txt", nous utilisons ce que @schoon a dit: 

split -b=1m -d file.txt file --additional-suffix=.txt

J'avais un fichier txt de 188,5 Mo et j'ai utilisé cette commande [mais avec -b5m pour les fichiers de 5,2 Mo], et il a renvoyé 35 fichiers fractionnés, tous des fichiers txt et 5,2 Mo, à l'exception du dernier, qui était de 5,0 Mo. Maintenant, comme je voulais que mes lignes restent entières, je voulais diviser le fichier principal tous les 1 million de lignes, mais la commande split ne me permettait même pas de faire -100000 encore moins "-1000000, donc un grand nombre de lignes à diviser ne travail. 

0
Ryan

Sur mon système Linux (Red Hat Enterprise 6.9), la commande split ne dispose pas des options de ligne de commande pour -n ou --additional-suffix.

Au lieu de cela, j'ai utilisé ceci:

split -d -l NUM_LINES really_big_file.txt split_files.txt.

-d consiste à ajouter un suffixe numérique à la fin du split_files.txt. et -l spécifie le nombre de lignes par fichier.

Par exemple, supposons que j'ai un très gros fichier comme ceci:

$ ls -laF
total 1391952
drwxr-xr-x 2 user.name group         40 Sep 14 15:43 ./
drwxr-xr-x 3 user.name group       4096 Sep 14 15:39 ../
-rw-r--r-- 1 user.name group 1425352817 Sep 14 14:01 really_big_file.txt

Ce fichier contient 100 000 lignes et je souhaite le scinder en fichiers de 30 000 lignes maximum. Cette commande va exécuter la scission et ajouter un entier à la fin du modèle de fichier de sortie split_files.txt..

$ split -d -l 30000 really_big_file.txt split_files.txt.

Les fichiers résultants sont fractionnés correctement avec au maximum 30 000 lignes par fichier.

$ ls -laF
total 2783904
drwxr-xr-x 2 user.name group        156 Sep 14 15:43 ./
drwxr-xr-x 3 user.name group       4096 Sep 14 15:39 ../
-rw-r--r-- 1 user.name group 1425352817 Sep 14 14:01 really_big_file.txt
-rw-r--r-- 1 user.name group  428604626 Sep 14 15:43 split_files.txt.00
-rw-r--r-- 1 user.name group  427152423 Sep 14 15:43 split_files.txt.01
-rw-r--r-- 1 user.name group  427141443 Sep 14 15:43 split_files.txt.02
-rw-r--r-- 1 user.name group  142454325 Sep 14 15:43 split_files.txt.03


$ wc -l *.txt*
    100000 really_big_file.txt
     30000 split_files.txt.00
     30000 split_files.txt.01
     30000 split_files.txt.02
     10000 split_files.txt.03
    200000 total
0

Essayez quelque chose comme ça:

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

for filename in *.txt; do mv "$filename" "Prefix_$filename"; done;
0
Morgan32