Как разделить файл на равные части, не разбивая отдельные строки? [дубликат]
этот вопрос уже есть ответ здесь:
Мне было интересно, можно ли разделить файл на равные части (edit: = все равны, кроме последнего), не нарушая линии? Используя раскол команда в Unix строки могут быть разбиты пополам. Есть ли способ, скажем, разделить файл на 5 равных частей, но все равно он состоит только из целых строк (это не проблема, если один из файлов немного больше или меньше)? Я знаю, что могу просто вычислить количество строк, но я должен сделать это для многих файлов в сценарии bash. Большое спасибо!
6 ответов
если вы имеете в виду равное количество линии, split
имеет вариант для этого:
split --lines=75
Если вам нужно знать, что это 75
должно быть действительно для N
равными частями, его:
lines_per_part = int(total_lines + N - 1) / N
где всего строк можно получить с wc -l
.
см. Следующий сценарий для примера:
#!/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.*
вот результаты:
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
более поздние версии split
позволяет указать количество из CHUNKS
С . Поэтому вы можете использовать что-то вроде:
split --number=l/6 ${fspec} xyzzy.
(это ell-slash-six
, что означает lines
, а не one-slash-six
).
это даст вам примерно равные файлы с точки зрения размера, без разделений средней линии.
я упоминаю этот последний пункт, потому что он не дает вам примерно столько же строки в каждом файле больше того же числа символы.
Итак, если у вас есть один 20-символьная строка и 19 1-символьных строк (всего двадцать строк) и разделите на пять файлов, скорее всего не четыре строки в каждом файле.
сценарий даже не нужен,сплит(1) поддерживает нужную функцию из коробки:split -l 75 auth.log auth.log.
Вышеуказанная команда разбивает файл на куски по 75 строк за штуку и выводит файл на форму:auth.log.aa, auth.log.ab, ...
wc -l
на исходном файле и выводе дает:
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 был обновлен в выпуске coreutils 8.8 (объявлено 22 декабря 2010 года) с опцией --number для создания определенного количества файлов. Опция --number=l / n генерирует n файлов без разделения строк.
http://www.gnu.org/software/coreutils/manual/html_node/split-invocation.html#split-invocation http://savannah.gnu.org/forum/forum.php?forum_id=6662
простое решение для простого вопроса:
split -n l/5 your_file.txt
нет необходимости в скриптах здесь.
l/N split into N files without splitting lines
Я сделал сценарий bash, который дал несколько частей в качестве входных данных, разделил файл
#!/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*
Я head
и tail
команды и хранить в файлах tmp, для разделения файлов
#10 means 10 parts
sh mysplitXparts.sh input_file 10
или с awk, где 0.1 10% => 10 частей, или 0.334 3 части
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"