Как разделить большой текстовый файл на меньшие файлы с равным количеством строк?
У меня есть большой (по количеству строк) текстовый файл, который я хотел бы разделить на меньшие файлы, а также по количеству строк. Поэтому, если мой файл имеет около 2M строк, я хотел бы разделить его на 10 файлов, содержащих 200k строк, или 100 файлов, содержащих 20k строк (плюс один файл с остатком; быть равномерно делимым не имеет значения).
Я мог бы сделать это довольно легко в Python, но мне интересно, есть ли какой-либо способ ниндзя сделать это с помощью bash и Unix utils (как против вручную зацикливания и подсчета / секционирования линий).
10 ответов
вы смотрели на команду split?
$ split --help
Usage: split [OPTION] [INPUT [PREFIX]]
Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default
size is 1000 lines, and default PREFIX is `x'. With no INPUT, or when INPUT
is -, read standard input.
Mandatory arguments to long options are mandatory for short options too.
-a, --suffix-length=N use suffixes of length N (default 2)
-b, --bytes=SIZE put SIZE bytes per output file
-C, --line-bytes=SIZE put at most SIZE bytes of lines per output file
-d, --numeric-suffixes use numeric suffixes instead of alphabetic
-l, --lines=NUMBER put NUMBER lines per output file
--verbose print a diagnostic to standard error just
before each output file is opened
--help display this help and exit
--version output version information and exit
вы могли бы сделать что-то вроде этого:
split -l 200000 filename
который будет создавать файлы с 200000 строк с именем xaa xab xac
...
другой вариант, разделенный по размеру выходного файла (по-прежнему разбивается на разрывы строк):
split -C 20m --numeric-suffixes input_filename output_prefix
создает такие файлы, как output_prefix01 output_prefix02 output_prefix03 ...
каждый из максимального размера 20 мегабайт.
использовать split
разделить файл на части фиксированного размера, создает выходные файлы, содержащие последовательные разделы ввода (стандартный ввод, если ни один не задан или вход `-')
Syntax
split [options] [INPUT [PREFIX]]
использование:
sed -n '1,100p' filename > output.txt
здесь 1 и 100-это номера строк, которые вы захватите в output.txt
.
в случае, если вы просто хотите разделить на x количество строк каждый файл, данный asnwers о split
ОК. Но, мне любопытно, что никто не обратил внимания на требования:
- "whithout должны считать их" - > с помощью wc + cut
- "имея остаток в дополнительном файле" - > split делает по умолчанию
Я не могу сделать это без "wc + cut", но я использую это:
split -l $(expr `wc $filename | cut -d ' ' -f3` / $chunks) $filename
Это можно легко добавить к вашим функциям bashrc, чтобы вы можно просто вызвать его, передавая имя файла и куски:
split -l $(expr `wc | cut -d ' ' -f3` / )
если вы хотите просто X кусков без остатка в дополнительном файле, просто адаптируйте формулу, чтобы суммировать ее (куски - 1) в каждом файле. Я использую этот подход, потому что обычно я просто хочу x количество файлов, а не x строк на файл:
split -l $(expr `wc | cut -d ' ' -f3` / + `expr - 1`)
вы можете добавить это в скрипт и назвать его своим "способом ниндзя", потому что, если ничто не соответствует вашим потребностям, вы можете построить его :-)
split
(из GNU coreutils, так как версии 8.8 от 2010-12-22) включает в себя следующий параметр:
-n, --number=CHUNKS generate CHUNKS output files; see explanation below
CHUNKS may be:
N split into N files based on size of input
K/N output Kth of N to stdout
l/N split into N files without splitting lines/records
l/K/N output Kth of N to stdout without splitting lines/records
r/N like 'l' but use round robin distribution
r/K/N likewise but only output Kth of N to stdout
таким образом, split -n 4 input output.
будет генерировать четыре файла (output.a{a,b,c,d}
) С тем же количеством байтов, но строки могут быть сломаны посередине.
если мы хотим сохранить полные строки (т. е. разделить на строки), то это должно работать:
split -n l/4 input output.
связанный ответ:https://stackoverflow.com/a/19031247
HDFS getmerge небольшой файл и разлитый в размер свойства.
этот метод вызовет разрыв строки
split-B 125m компактный.файл-d-A 3 compact_prefix
Я пытаюсь getmerge и разделить примерно на 128MB каждый файл.
split в 128m, судья sizeunit M или G, пожалуйста, проверьте перед использованием.
begainsize=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print }' `
sizeunit=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print }' `
if [ $sizeunit = "G" ];then
res=$(printf "%.f" `echo "scale=5;$begainsize*8 "|bc`)
else
res=$(printf "%.f" `echo "scale=5;$begainsize/128 "|bc`) # celling ref http://blog.csdn.net/naiveloafer/article/details/8783518
fi
echo $res
# split into $res files with number suffix. ref http://blog.csdn.net/microzone/article/details/52839598
compact_file_name=$compact_file"_"
echo "compact_file_name :"$compact_file_name
split -n l/$res $basedir/$compact_file -d -a 3 $basedir/${compact_file_name}