Je me demandais s'il était possible de diviser un fichier en parties égales (edit: = tous égaux sauf le dernier), sans rompre la ligne? En utilisant la commande split sous Unix, les lignes peuvent être divisées en deux. Existe-t-il un moyen, par exemple, de scinder un fichier en 5 parties égales, mais de ne le garder que sous forme de lignes entières (aucun problème si l’un des fichiers est un peu plus gros ou plus petit)? Je sais que je pourrais simplement calculer le nombre de lignes, mais je dois le faire pour beaucoup de fichiers dans un script bash. Merci beaucoup!
Si vous voulez dire un nombre égal de lignes, split
a une option pour cela:
split --lines=75
Si vous avez besoin de savoir ce que cela 75
devrait vraiment être pour N
parts égales, c'est:
lines_per_part = int(total_lines + N - 1) / N
où le nombre total de 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.*
Cela génère:
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 le -n/--number
option. Vous pouvez donc utiliser quelque chose comme:
split --number=l/6 ${fspec} xyzzy.
(c'est ell-slash-six
, signifiant lines
, pas one-slash-six
).
Cela vous donnera à peu près les mêmes fichiers en termes de taille, sans division en milieu de ligne.
Je mentionne ce dernier point car il ne vous donne pas à peu près le même nombre de lignes dans chaque fichier, plus le même nombre de lignes caractères.
Donc, si vous avez une ligne de 20 caractères et 19 lignes de 1 caractère (vingt lignes au total) et que vous vous séparez en cinq fichiers, vous ne le ferez probablement pas obtenir quatre lignes dans chaque fichier.
Le script n'est même pas nécessaire, split (1) supporte la fonctionnalité voulue immédiatement:split -l 75 auth.log auth.log.
_ La commande ci-dessus divise le fichier en morceaux de 75 lignes et génère le fichier sous la forme: auth.log.aa, auth.log.ab, ...
wc -l
sur le fichier d'origine et la 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
split a été mis à 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 fractionner les lignes.
http://www.gnu.org/software/coreutils/manual/html_node/split-invocation.html#split-invocationhttp://savannah.gnu.org/forum/ forum.php? forum_id = 6662
Une solution simple pour une question simple:
split -n l/5 your_file.txt
pas besoin de script ici.
Dans le fichier man , CHUNKS may be:
l/N split into N files without splitting lines
Mettre à jour
Toutes les distributions Unix n'incluent pas ce drapeau. Par exemple, cela ne fonctionnera pas sous OSX. Pour l'utiliser, vous pouvez envisager en remplaçant les utilitaires Mac OS X par GNU) .
J'ai fait un script bash, qui donne un certain nombre de parties en entrée, divise un fichier
#!/bin/sh
parts_total="$2";
input="$1";
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é les commandes head
et tail
, et les ai stockées dans des fichiers tmp, pour scinder 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="[email protected][email protected]";
string[] tokens = line.Split(new char[] { '=' }, 2, 0);
ans:
tokens[0]=to
token[1][email protected][email protected]"