Comment diviser un fichier en parties égales, sans rupture de lignes individuelles? [dupliquer]
cette question a déjà une réponse ici:
- comment diviser un gros fichier texte en plus petits fichiers avec le même nombre de lignes? 10 réponses
je me demandais s'il était possible de diviser un fichier en parties égales ( edit: = toutes égales sauf dernier), sans rupture de la chaîne? En utilisant la commande split dans Unix, les lignes peuvent être brisées en deux. Est-il un moyen, par exemple, diviser un fichier en 5 parties égales, mais il a encore seulement constitués de l'ensemble des lignes (il n'est pas un problème si l'un des fichiers est un peu plus grand ou plus petit)? Je sais que je pourrais juste calculer le nombre de lignes, mais je dois le faire pour beaucoup de fichiers dans un script bash. Merci beaucoup!
6 réponses
si vous voulez dire un nombre égal de lignes, split
a une option pour ceci:
split --lines=75
si vous avez besoin de savoir ce que 75
devrait vraiment être pour N
parties égales, its:
lines_per_part = int(total_lines + N - 1) / N
où le total des lignes peut être obtenu avec wc -l
.
voir le script suivant pour un exemple:
#!/usr/bin/bash
# Configuration stuff
fspec=qq.c
num_files=6
# Work out lines per file.
total_lines=$(wc -l <${fspec})
((lines_per_file = (total_lines + num_files - 1) / num_files))
# Split the actual file, maintaining lines.
split --lines=${lines_per_file} ${fspec} xyzzy.
# Debug information
echo "Total lines = ${total_lines}"
echo "Lines per file = ${lines_per_file}"
wc -l xyzzy.*
Ce sorties:
Total lines = 70
Lines per file = 12
12 xyzzy.aa
12 xyzzy.ab
12 xyzzy.ac
12 xyzzy.ad
12 xyzzy.ae
10 xyzzy.af
70 total
les versions plus récentes de split
vous permettent de spécifier un nombre de CHUNKS
avec l'option -n/--number
. Vous pouvez donc utiliser quelque chose comme:
split --number=l/6 ${fspec} xyzzy.
(c'est-à-dire ell-slash-six
, qui signifie lines
, et non one-slash-six
).
qui vous donnera des fichiers à peu près égaux en termes de taille, sans fentes de ligne médiane.
je mentionne ce dernier point parce qu'il ne vous donne pas à peu près le même nombre de lignes dans chaque fichier, plus le même nombre de caractères.
donc, si vous avez une ligne de 20 caractères et 19 lignes de 1 caractère (vingt lignes au total) et divisé en cinq fichiers, vous très probablement ne pas obtenir quatre lignes dans chaque fichier.
le script n'est même pas nécessaire, split (1) prend en charge le trait voulu hors de la boîte:
split -l 75 auth.log auth.log.
La commande ci-dessus divise le fichier en morceaux de 75 lignes par pièce, et produit le fichier sur la forme: auth.log.aa, auth.log.ab, ...
wc -l
sur le fichier original et de sortie donne:
321 auth.log
75 auth.log.aa
75 auth.log.ab
75 auth.log.ac
75 auth.log.ad
21 auth.log.ae
642 total
a été mise à jour dans la version 8.8 de coreutils (annoncée le 22 décembre 2010) avec l'option --number pour générer un nombre spécifique de fichiers. L'option --number=l/n génère n fichiers sans séparer les lignes.
http://www.gnu.org/software/coreutils/manual/html_node/split-invocation.html#split-invocation http://savannah.gnu.org/forum/forum.php?forum_id=6662
j'ai fait un script bash, qui a donné un certain nombre de parties comme entrée, a divisé un fichier
#!/bin/sh
parts_total="";
input="";
parts=$((parts_total))
for i in $(seq 0 $((parts_total-2))); do
lines=$(wc -l "$input" | cut -f 1 -d" ")
#n is rounded, 1.3 to 2, 1.6 to 2, 1 to 1
n=$(awk -v lines=$lines -v parts=$parts 'BEGIN {
n = lines/parts;
rounded = sprintf("%.0f", n);
if(n>rounded){
print rounded + 1;
}else{
print rounded;
}
}');
head -$n "$input" > split${i}
tail -$((lines-n)) "$input" > .tmp${i}
input=".tmp${i}"
parts=$((parts-1));
done
mv .tmp$((parts_total-2)) split$((parts_total-1))
rm .tmp*
j'ai utilisé head
et tail
commandes, et stocker dans les fichiers tmp, pour diviser les fichiers
#10 means 10 parts
sh mysplitXparts.sh input_file 10
ou avec awk, où 0,1 est 10% => 10 parties, ou 0,334 est 3 parties
awk -v size=$(wc -l < input) -v perc=0.1 '{
nfile = int(NR/(size*perc));
if(nfile >= 1/perc){
nfile--;
}
print > "split_"nfile
}' input
var dict = File.ReadLines("test.txt")
.Where(line => !string.IsNullOrWhitespace(line))
.Select(line => line.Split(new char[] { '=' }, 2, 0))
.ToDictionary(parts => parts[0], parts => parts[1]);
or
enter code here
line="to=xxx@gmail.com=yyy@yahoo.co.in";
string[] tokens = line.Split(new char[] { '=' }, 2, 0);
ans:
tokens[0]=to
token[1]=xxx@gmail.com=yyy@yahoo.co.in"