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

Bash 如何将一个大的文本文件拆分为行数相等的小文件?,bash,file,unix,Bash,File,Unix,我有一个大的(按行数)纯文本文件,我想把它分成更小的文件,也按行数。因此,如果我的文件有大约2M行,我想将其拆分为10个包含200k行的文件,或者100个包含20k行的文件(加上一个包含剩余行的文件;可以均匀分割并不重要) 我可以用Python很容易地做到这一点,但我想知道是否有什么忍者方法可以使用bash和unix UTIL来做到这一点(而不是手动循环和计数/分区行)。您看过split命令了吗 $split--帮助 用法:拆分[选项][输入[前缀]] 将固定大小的输入输出到PREFIXaa、P

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


我可以用Python很容易地做到这一点,但我想知道是否有什么忍者方法可以使用bash和unix UTIL来做到这一点(而不是手动循环和计数/分区行)。

您看过split命令了吗

$split--帮助
用法:拆分[选项][输入[前缀]]
将固定大小的输入输出到PREFIXaa、PREFIXab、。。。;违约
大小为1000行,默认前缀为'x'。没有输入,或输入时
是-,读取标准输入。
长选项的强制性参数对于短选项也是强制性的。
-a、 --后缀长度=N使用长度为N的后缀(默认为2)
-b、 --bytes=大小每个输出文件放置大小字节
-C、 --line bytes=每个输出文件的最大行大小字节
-d、 --数字后缀使用数字后缀而不是字母后缀
-l、 --行数=每个输出文件的行数
--详细打印诊断到标准错误
在打开每个输出文件之前
--帮助显示此帮助并退出
--版本输出版本信息并退出
你可以这样做:

split -l 200000 filename
这将创建文件,每个文件有200000行,名为
xaa-xab-xac

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

创建最大大小为20兆字节的文件,如
output\u prefix01 output\u prefix02 output\u prefix03…

使用
split

将文件拆分为固定大小的部分,创建包含连续输入部分的输出文件(如果未提供任何输入或输入为“-”,则为标准输入)

语法
拆分[选项][输入[前缀]]

命令如何


是的,有一个
split
命令。它将按行或字节分割文件

$split--帮助
用法:拆分[选项]。。。[输入[前缀]]
将固定大小的输入输出到PREFIXaa、PREFIXab、。。。;违约
大小为1000行,默认前缀为'x'。没有输入,或输入时
是-,读取标准输入。
长选项的强制性参数对于短选项也是强制性的。
-a、 --后缀长度=N使用长度为N的后缀(默认为2)
-b、 --bytes=大小每个输出文件放置大小字节
-C、 --line bytes=每个输出文件的最大行大小字节
-d、 --数字后缀使用数字后缀而不是字母后缀
-l、 --行数=每个输出文件的行数
--在每次诊断之前详细打印诊断
输出文件已打开
--帮助显示此帮助并退出
--版本输出版本信息并退出
大小可能有一个乘数后缀:
b 512,kB 1000,K 1024,MB 1000*1000,M 1024*1024,
GB 1000*1000*1000、G 1024*1024*1024等表示T、P、E、Z、Y。
您也可以使用awk

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


这里,1和100是您将在
output.txt

中捕获的行号。如果您只想按每个文件的x行数进行拆分,那么关于
拆分的给定答案就可以了。但是,我对没有人关注需求感到好奇:

  • “无需计数”->使用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个块,而不包含余数,只需调整公式,对每个文件求和(chunks-1)。我使用这种方法是因为通常我只需要x个文件,而不是每个文件x行:

split -l  $(expr `wc $1 | cut -d ' ' -f3` / $2 + `expr $2 - 1`) $1

您可以将其添加到脚本中并称之为“忍者之道”,因为如果没有任何东西满足您的需要,您可以构建它:-)

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}
将文件“file.txt”拆分为10000行文件:

split -l 10000 file.txt
split
(来自GNU coreutils,因为)包括以下参数:

-n,--number=块生成块输出文件;见下面的解释
块可以是:
N根据输入的大小拆分为N个文件
K/N输出第K个N到标准输出
l/N拆分为N个文件,不拆分行/记录
l/K/N在不拆分行/记录的情况下向标准输出第K个N
r/N类似于“l”,但使用循环分布
r/K/N类似,但仅将N的第K个输出到标准输出
< > >代码>分裂-N 4输入输出.<代码>将生成四个文件(<代码>输出,{a,b,c,d} <代码>),字节数相同,但中间可能有行。

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

split-nl/4输入输出。

相关答案:

出于好奇,它们被“拆分”后,如何“组合”它们?类似“cat part2>>part1”的内容?或者有其他忍者工具吗?介意更新您的问题吗?要把它放回一起,
cat part*>original
yes cat是concatenate的缩写。一般来说,apropos有助于找到合适的命令。即见:apropos的输出split@pixelbeat这很酷,谢天谢地,OSX用户应该确保他们的文件包含LINUX或UNIX风格的换行符/行结束指示器(LF),而不是MAC OS X风格的行结束指示器(CR)-如果类似的中断是回车而不是换行符,则split和csplit命令将不起作用。Te
split -b 125m compact.file -d -a 3 compact_prefix
# 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}
split -l 10000 file.txt