如何将大文本文件拆分为具有相同行数的较小文件?

时间:2010-01-06 22:40:40

标签: bash file unix

我有一个大的(按行数)纯文本文件,我想分成较小的文件,也按行数分割。因此,如果我的文件大约有2M行,我想把它分成10个包含200k行的文件,或者包含20k行的100个文件(加上一个包含剩余部分的文件;可以被整除的无关紧要)。 / p>

我可以在Python中相当容易地做到这一点,但我想知道是否有任何一种使用bash和unix utils的忍者方法(而不是手动循环和计数/分区行)。

10 个答案:

答案 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 ...

的200000行的文件

另一个选项,按输出文件的大小分割(仍然在换行符上拆分):

 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]]

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

答案 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
  • “将余数留在额外档案中” - >默认情况下拆分

如果没有“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.

相关答案:https://stackoverflow.com/a/19031247

答案 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}