bash - txt - ¿Cómo dividir un archivo en partes iguales, sin romper líneas individuales?
como dividir un archivo zip en partes (6)
Esta pregunta ya tiene una respuesta aquí:
Me preguntaba si era posible dividir un archivo en partes iguales ( editar: = todos iguales excepto el último), sin romper la línea? Usando el comando dividir en Unix, las líneas pueden dividirse por la mitad. ¿Hay alguna forma de, por ejemplo, dividir un archivo en 5 partes iguales, pero que solo consista en líneas completas (no hay problema si uno de los archivos es un poco más grande o más pequeño)? Sé que podría calcular el número de líneas, pero tengo que hacer esto para muchos archivos en un script bash. ¡Muchas gracias!
El script ni siquiera es necesario, split(1) admite la función deseada de fábrica:
split -l 75 auth.log auth.log.
El comando anterior divide el archivo en fragmentos de 75 líneas por pieza y genera un archivo en el formulario: auth.log.aa, auth.log.ab, ...
wc -l
en el archivo original y la salida da:
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
Hice un script bash, que dadas varias partes como entrada, dividí un archivo
#!/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*
tail
comandos de head
y tail
, y almacené en archivos tmp, para dividir los archivos
#10 means 10 parts
sh mysplitXparts.sh input_file 10
o con awk, donde 0.1 es 10% => 10 partes, o 0.334 es 3 partes
awk -v size=$(wc -l < input) -v perc=0.1 ''{
nfile = int(NR/(size*perc));
if(nfile >= 1/perc){
nfile--;
}
print > "split_"nfile
}'' input
Si se refiere a la misma cantidad de líneas, la split
tiene una opción para esto:
split --lines=75
Si necesita saber qué es lo que 75
realmente debería ser para N
partes iguales, es:
lines_per_part = int(total_lines + N - 1) / N
donde se pueden obtener líneas totales con wc -l
.
Vea la siguiente secuencia de comandos para un ejemplo:
#!/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.*
Esto 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
Las versiones más recientes de split
permiten especificar un número de CHUNKS
con la opción de -n/--number
. Por lo tanto, puede usar algo como:
split --number=l/6 ${fspec} xyzzy.
(eso es ell-slash-six
, que significa lines
, no one-slash-six
).
Eso le dará archivos aproximadamente iguales en términos de tamaño, sin divisiones en la línea media.
Menciono ese último punto porque no le da aproximadamente el mismo número de líneas en cada archivo, más el mismo número de caracteres.
Entonces, si tiene una línea de 20 caracteres y 19 líneas de 1 carácter (veinte líneas en total) y se divide en cinco archivos, lo más probable es que no obtenga cuatro líneas en cada archivo.
Una solución simple para una pregunta simple:
split -n l/5 your_file.txt
no hay necesidad de secuencias de comandos aquí.
Desde el archivo man , CHUNKS may be:
l/N split into N files without splitting lines
split se actualizó en la versión coreutils 8.8 (anunciada el 22 de diciembre de 2010) con la opción --number para generar un número específico de archivos. La opción --number = l / n genera n archivos sin dividir líneas.
http://www.gnu.org/software/coreutils/manual/html_node/split-invocation.html#split-invocation http://savannah.gnu.org/forum/forum.php?forum_id=6662
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]"