Как разделить большой текстовый файл на меньшие файлы с равным количеством строк?

У меня есть большой (по количеству строк) текстовый файл, который я хотел бы разделить на меньшие файлы, а также по количеству строк. Поэтому, если мой файл имеет около 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 -l 200000 mybigfile.txt

Да, есть


использовать split

разделить файл на части фиксированного размера, создает выходные файлы, содержащие последовательные разделы ввода (стандартный ввод, если ни один не задан или вход `-')

Syntax split [options] [INPUT [PREFIX]]

http://ss64.com/bash/split.html


использование:

sed -n '1,100p' filename > output.txt

здесь 1 и 100-это номера строк, которые вы захватите в output.txt.


вы также можете использовать awk

awk -vc=1 'NR%200000==0{++c}{print  > c".txt"}' largefile

разбить файл файл".txt " в 10000 строк файлов:

split -l 10000 file.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}