Как разбить большой текстовый файл на более мелкие файлы с одинаковым количеством строк?
У меня есть большой (по количеству строк) простой текстовый файл, который я хотел бы разбить на более мелкие файлы, в том числе по количеству строк. Поэтому, если мой файл имеет около 2M строк, я бы хотел разделить его на 10 файлов, содержащих 200k строк, или 100 файлов, содержащих 20k строк (плюс один файл с остатком; быть равномерно делимым не имеет значения).
Я мог бы сделать это довольно легко в Python, но мне интересно, есть ли какой-нибудь способ ниндзя сделать это, используя утилиты bash и unix (в отличие от ручного зацикливания и подсчета / разбиения строк).
12 ответов
Вы смотрели на команду 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
команда. Он разделит файл на строки или байты.
$ 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 just before each
output file is opened
--help display this help and exit
--version output version information and exit
SIZE may have a multiplier suffix:
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.
Чтобы разделить большой текстовый файл на более мелкие файлы по 1000 строк в каждом:
split <file> -l 1000
Чтобы разделить большой двоичный файл на более мелкие файлы по 10 МБ каждый:
split <file> -b 10M
Чтобы объединить разделенные файлы в один файл:
cat x* > <file>
Разделите файл, каждый раздел имеет 10 строк (кроме последнего разделения):
split -l 10 filename
Разделить файл на 5 файлов. Файл разбивается таким образом, что каждый разбиение имеет одинаковый размер (кроме последнего разбиения):
split -n 5 filename
Разделить файл с 512 байтами в каждом разделении (кроме последнего разделения; используйте 512 КБ для килобайт и 512 м для мегабайт):
split -b 512 filename
Разделите файл с не более чем 512 байтами в каждом разделении без разрыва строк:
split -C 512 filename
--> автор: cht.sh
Разбить файл "file.txt" на 10000 строк файлов:
split -l 10000 file.txt
Использование split
Разбивает файл на части фиксированного размера, создает выходные файлы, содержащие последовательные разделы INPUT (стандартный ввод, если ничего не задано или INPUT равен `- ')
Syntax
split [options] [INPUT [PREFIX]]
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.
Соответствующий ответ: /questions/36759205/kak-razbit-odin-tekstovyij-fajl-na-neskolko-fajlov-txt/36759213#36759213
Вы также можете использовать awk
awk -vc=1 'NR%200000==0{++c}{print $0 > c".txt"}' largefile
Использование:
sed -n '1,100p' filename > output.txt
Здесь 1 и 100 - номера строк, которые вы будете записывать в output.txt
,
В случае, если вы просто хотите разделить на x количество строк в каждом файле, данный ответ split
ОК. Но мне интересно, чтобы никто не обращал внимания на требования:
- "без них надо считать" -> используя wc + cut
- "имея остаток в дополнительном файле" -> по умолчанию делает split
Я не могу сделать это без "wc + cut", но я использую это:
split -l $(expr `wc $filename | cut -d ' ' -f3` / $chunks) $filename
Это может быть легко добавлено к вашим функциям bashrc, так что вы можете просто вызвать его, передавая имя файла и куски:
split -l $(expr `wc $1 | cut -d ' ' -f3` / $2) $1
Если вам нужно только x кусков без остатка в дополнительном файле, просто измените формулу, чтобы суммировать ее (куски - 1) в каждом файле. Я использую этот подход, потому что обычно я просто хочу х число файлов, а не х строк на файл:
split -l $(expr `wc $1 | cut -d ' ' -f3` / $2 + `expr $2 - 1`) $1
Вы можете добавить это в скрипт и назвать его "ниндзя-путь", потому что, если ничто не соответствует вашим потребностям, вы можете создать его:-)
Вот пример разделения файла "toSplit.txt" на более мелкие файлы по 200 строк с именами "splited00.txt", splited01.txt, ..., "splited25.txt"...
split -l 200 --numeric-suffixes --additional-suffix=".txt" toSplit.txt splited
HDFS getmerge небольшой файл и разлитый в размер свойства.
Этот метод вызовет разрыв строки
split -b 125m compact.file -d -a 3 compact_prefix
Я пытаюсь объединить и разделить на 128 МБ каждый файл.
разделить на 128 м, размер судьи - M или G, пожалуйста, проверьте перед использованием.
begainsize=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print $1}' `
sizeunit=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print $2}' `
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}