我有一个大的(按行数)纯文本文件,我想分成较小的文件,也按行数分割。因此,如果我的文件大约有2M行,我想把它分成10个包含200k行的文件,或者包含20k行的100个文件(加上一个包含剩余部分的文件;可以被整除的无关紧要)。 / p>
我可以在Python中相当容易地做到这一点,但我想知道是否有任何一种使用bash和unix utils的忍者方法(而不是手动循环和计数/分区行)。
答案 0 :(得分:744)
你看过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
将创建每个包含名为xaa xab xac
...
另一个选项,按输出文件的大小分割(仍然在换行符上拆分):
split -C 20m --numeric-suffixes input_filename output_prefix
创建类似output_prefix01 output_prefix02 output_prefix03 ...
的文件,每个文件最大大小为20兆字节。
答案 1 :(得分:74)
split命令怎么样?
split -l 200000 mybigfile.txt
答案 2 :(得分:37)
是的,有一个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.
答案 3 :(得分:14)
使用split
将文件拆分为固定大小的片段,创建包含INPUT连续部分的输出文件(如果没有给出标准输入或INPUT为' - ')
Syntax
split [options] [INPUT [PREFIX]]
答案 4 :(得分:13)
使用:
sed -n '1,100p' filename > output.txt
此处,1和100是您将在output.txt
中捕获的行号。
答案 5 :(得分:10)
拆分文件" file.txt"进入10000行文件:
split -l 10000 file.txt
答案 6 :(得分:8)
你也可以使用awk
awk -vc=1 'NR%200000==0{++c}{print $0 > c".txt"}' largefile
答案 7 :(得分:7)
如果您只想按每个文件的x行分割,则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)。我确实使用这种方法,因为通常我只需要x个文件而不是每个文件x行:
split -l $(expr `wc $1 | cut -d ' ' -f3` / $2 + `expr $2 - 1`) $1
您可以将其添加到脚本中并将其称为“忍者方式”,因为如果没有任何内容可以满足您的需求,您可以构建它: - )
答案 8 :(得分:7)
split
(来自GNU coreutils,因为version 8.8 from 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.
答案 9 :(得分:0)
HDFS getmerge小文件并溢出到属性大小。
此方法将导致换行
split -b 125m compact.file -d -a 3 compact_prefix
我尝试将每个文件合并到大约128MB。
# split into 128m ,judge sizeunit is M or G ,please test before use.
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}