Come dividere un file in parti uguali, senza rompere le singole righe?

Mi chiedevo se fosse ansible dividere un file in parti uguali ( modifica: = tutto uguale tranne per l’ultimo), senza interrompere la linea? Usando il comando split in Unix, le linee possono essere spezzate a metà. C’è un modo per, diciamo, dividere un file in 5 parti uguali, ma farlo contenere solo righe intere (non è un problema se uno dei file è un po ‘più big o più piccolo)? So che potrei solo calcolare il numero di linee, ma devo farlo per un sacco di file in uno script bash. Grazie molto!

Se si intende un numero uguale di linee, split ha un’opzione per questo:

 split --lines=75 

Se hai bisogno di sapere che cosa dovrebbe essere veramente 75 per N parti uguali, è:

 lines_per_part = int(total_lines + N - 1) / N 

dove le linee totali possono essere ottenute con wc -l .

Vedi il seguente script per un esempio:

 #!/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.* 

Questo produce:

 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 

Le versioni più recenti di split consentono di specificare un numero di CHUNKS con l'opzione -n/--number . Puoi quindi usare qualcosa come:

 split --number=l/6 ${fspec} xyzzy. 

(questo è ell-slash-six , che significa lines , non one-slash-six ).

Ciò ti darà file approssimativamente uguali in termini di dimensioni, senza divisioni a metà linea.

Cito l'ultimo punto perché non ti dà più o meno lo stesso numero di righe in ogni file, più lo stesso numero di caratteri.

Quindi, se hai una linea di 20 caratteri e 19 linee di 1 carattere (venti righe in totale) e dividi cinque file, molto probabilmente non otterrai quattro righe in ogni file.

Lo script non è nemmeno necessario, split (1) supporta la funzionalità desiderata out of the box:
split -l 75 auth.log auth.log. Il comando precedente divide il file in blocchi di 75 righe un pezzo e restituisce il file nel modulo: auth.log.aa, auth.log.ab, ...

wc -l sul file originale e l’output fornisce:

  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 è stato aggiornato in coreutils versione 8.8 (annunciato il 22 dicembre 2010) con l’opzione –number per generare un numero specifico di file. L’opzione –number = l / n genera n file senza linee di divisione.

http://www.gnu.org/software/coreutils/manual/html_node/split-invocation.html#split-invocation http://savannah.gnu.org/forum/forum.php?forum_id=6662

Una soluzione semplice per una semplice domanda:

 split -nl/5 your_file.txt 

non c’è bisogno di scripting qui.

Dal file man , CHUNKS may be:

 l/N split into N files without splitting lines 

Ho creato uno script bash, che ha dato un numero di parti come input, dividere un file

 #!/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* 

Ho usato tail comandi head e tail e archiviato nei file tmp, per dividere i file

 #10 means 10 parts sh mysplitXparts.sh input_file 10 

o con awk, dove 0.1 è 10% => 10 parti o 0,334 è 3 parti

 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]"