如何将大文本文件拆分为行数相等的小文件?

Posted

技术标签:

【中文标题】如何将大文本文件拆分为行数相等的小文件?【英文标题】:How can I split a large text file into smaller files with an equal number of lines? 【发布时间】:2011-01-02 06:42:47 【问题描述】:

我有一个大的(按行数)纯文本文件,我想将它拆分成更小的文件,也按行数。因此,如果我的文件大约有 2M 行,我想将其拆分为 10 个包含 200k 行的文件,或 100 个包含 20k 行的文件(加上一个文件,其余部分;被均匀整除并不重要)。

我可以在 Python 中相当容易地做到这一点,但我想知道是否有任何忍者方法可以使用 Bash 和 Unix 实用程序来做到这一点(而不是手动循环和计算/分区行)。

【问题讨论】:

出于好奇,它们“分裂”后,如何“组合”它们?像“猫第 2 部分 >> 第 1 部分”之类的东西?还是有另一个忍者实用程序?介意更新您的问题吗? 重新组合,cat part* > original 是的 cat 是连接的缩写。一般来说,apropos 对于查找适当的命令很有用。 IE。查看输出:apropos split @pixelbeat 太酷了,谢谢 顺便说一句,OS X 用户应确保他们的文件包含 LINUX 或 UNIX 样式的换行符/行尾指示符 (LF) 而不是 MAC OS X 样式的行尾指示器 (CR) - 如果您喜欢的中断是回车而不是换行,则 split 和 csplit 命令将不起作用。如果您使用的是 Mac OS,BareBones 软件的 TextWrangler 可以为您提供帮助。您可以选择您希望换行符的外观。当您保存(或另存为...)您的文本文件时。 【参考方案1】:

看看拆分命令:

$ 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 -b 200m filename(m 表示兆字节,k 表示千字节或字节不​​带后缀) 按大小分割并确保文件在换行符处分割:split -C 200m filename split 使用 Unicode (UTF-16) 输入产生乱码输出。至少在我拥有的版本的 Windows 上。 @geotheory,请务必遵循 LeberMac 在线程前面关于首先使用 TextWrangler 或 BBEdit 将 CR (Mac) 行结尾转换为 LR (Linux) 行结尾的建议。在我找到那条建议之前,我遇到了和你完全相同的问题。 -d 选项在 OSX 上不可用,请改用 gsplit。希望这对 Mac 用户有用。【参考方案2】:

使用split 命令:

split -l 200000 mybigfile.txt

【讨论】:

【参考方案3】:

是的,有一个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.

【讨论】:

试过 georgec@ATGIS25 ~ $ split -l 100000 /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands/trc_longlands.txt 但目录中没有拆分文件 - 输出在哪里? 应该在同一个目录下。例如。如果我想将每个文件拆分为 1,000,000 行,请执行以下操作:split -l 1000000 train_file train_file. 并在同一目录中,我将获得前一百万的 train_file.aa,然后是下一百万的 trail_file.ab,等等。 @GeorgeC 并且您可以获得带有前缀的自定义输出目录:split input my/dir/【参考方案4】:

使用split:

将文件拆分为固定大小的片段,创建包含连续 INPUT 部分的输出文件(如果没有给出标准输入或 INPUT 为 `-',则为标准输入)

Syntax split [options] [INPUT [PREFIX]]

【讨论】:

【参考方案5】:

将文件“file.txt”拆分为 10,000 行文件:

split -l 10000 file.txt

【讨论】:

【参考方案6】:

用途:

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

这里,1 和 100 是您将在 output.txt 中捕获的行号。

【讨论】:

这仅获取前 100 行,您需要循环它以连续将文件拆分为下一个 101..200 等。或者像这里所有的***答案已经告诉你的那样,只使用split .【参考方案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.aa,b,c,d),但中间可能会出现断行。

如果我们想保留完整的行(即按行分割),那么这应该可行:

split -n l/4 input output.

相关回答:https://***.com/a/19031247

【讨论】:

【参考方案8】:

你也可以使用AWK:

awk -vc=1 'NR%200000==0++cprint $0 > c".txt"' largefile

【讨论】:

awk -v lines=200000 -v fmt="%d.txt" 'print>sprintf(fmt,1+int((NR-1)/lines))' with prefix: awk -vc=1 'NR%200000==0++cprint $0 > "prefix"c".txt"' largefile【参考方案9】:

如果您只想将每个文件按 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

您可以将其添加到脚本中并将其称为您的“忍者方式”,因为如果没有适合您的需求,您可以构建它:-)

【讨论】:

或者,只需使用split-n 选项。【参考方案10】:

HDFS getmerge 小文件并分割成合适的大小。

这种方法会导致换行:

split -b 125m compact.file -d -a 3 compact_prefix

我尝试 getmerge 并将每个文件拆分为大约 128 MB。

# Split into 128 MB, and 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 a 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

【讨论】:

什么是“HDFS”? Hadoop distributed file system?或者是其他东西?你能提供一个参考吗? 什么是“celling”和“begain”?后者是“开始”(或“开始”)吗?

以上是关于如何将大文本文件拆分为行数相等的小文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 按行号将大文本文件拆分为较小的文本文件

将大文本文件加载到richtextbox c# [重复]

javascript 将文本文件或csv拆分为指定行数的较小文件

如何将大文件(12gb)拆分为多个 1GB 压缩(.gz)档案? C#

如何使用 vertx 拆分和合并文件 [关闭]

C# - 将大 (150MB) 文本文件读入富文本框