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
(...)?
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
.
$ split -l 100 input_file output_file
où -l
est le nombre de lignes dans chaque fichier. Cela va créer:
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
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.
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
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.
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.
où -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
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;