我有一个文件包含一些行。我希望将文件拆分为具有特定名称的n个文件。每个文件中存在多少行并不重要。我只想要特别的no.of文件(比如5)。这里的问题是原始文件中的行号不断变化。所以我需要计算没有行,然后将文件分成5个部分。如果可能,我们必须将它们分别发送到不同的目录。
答案 0 :(得分:37)
在bash中,您可以使用split
命令根据所需的行数进行拆分。您可以使用wc
命令确定需要多少行。这里的wc
与split
合并为一行。
例如,将onepiece.log
分成5部分
split -l$((`wc -l < onepiece.log`/5)) onepiece.log onepiece.split.log -da 4
这会创建onepiece.split.log0000
...
注意:bash部分向下舍入,因此如果有剩余部分则会有第6部分文件。
答案 1 :(得分:6)
在linux上,有一个split
命令,
split --lines=1m /path/to/large/file /path/to/output/file/prefix
将固定大小的INPUT输出到PREFIXaa,PREFIX,...;默认大小为1000行,默认PREFIX为“x”。没有INPUT,或INPUT为 - 时,读取标准输入。
...
-l, - lines = NUMBER 每个输出文件放入NUMBER行
...
但是,您必须事先计算分割的实际大小。
答案 2 :(得分:6)
假设您正在处理文本文件,然后wc -l
确定要分割成指定行数的总行数和split -l
(在您的情况下为总数/ 5)。这适用于UNIX / Mac和Windows(如果安装了cygwin)
答案 3 :(得分:3)
split具有选项“ --number = CHUNKS”,可用于将文件划分为多个块。 这是来自“ split --help”的(修剪后的)输出:
-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
l/K/N output Kth of N to stdout without splitting lines
r/N like 'l' but use round robin distribution
r/K/N likewise but only output Kth of N to stdout
在将其分为5部分的情况下,命令为:
split --number=l/5 inputfile outputprefix
但这可能不会导致它们具有相同的行数。
如果希望它们直到最后一行都具有相同数量的行,则可以使用以下命令:
split -l $(( ($(cat "inputfile" | wc -l) + 5 - 1)/5 )) inputfile outputprefix
此处的两个5都可以用任何其他数字替换(确保它们相同)。
下面是对该命令的逐个解释:
$( )
返回您输入的任何命令的输出。 cat用于确保wc仅返回行数而不输出输入文件名。
$(( ))
将您放在括号之间的任何内容作为数学表达式(仅使用整数)进行求值,并返回结果。
($(cat "inputfile" | wc -l) + 5 - 1)/5
接受输入文件的行数,然后加5,减1,然后将结果除以5。除法之前的加法和减法确保结果被四舍五入,以便给出准确的数字您想要的零件数(在这种情况下为5)。
您还可以使用split --number=r/5
将其拆分为四个文件,每个文件之间分配一行,如下例所示:
inputfile.txt:
1
2
3
4
5
6
7
8
9
outputfile1:
1
6
outputfile2:
2
7
outputfile3:
3
8
outputfile4:
4
9
outputfile5:
5
这不会保留文件顺序。但这在不重要的情况下很有用。
答案 4 :(得分:1)
这是基于@sketchytechky和@grasshopper给出的原始答案的。如果您想以不同的方式处理余数,并希望输出固定数量的文件,但循环分配行,则split命令应写为:
split -da 4 -n r/1024 filename filename_split --additional-suffix=".log"
。将1024替换为您想要作为输出的文件数。
答案 5 :(得分:0)
我可以想到几种方法。您将使用哪种方法取决于数据。
行是固定长度的:通过读取文件的目录条目来查找文件的大小,然后除以行长度以获得行数。使用它来确定每个文件的行数。
文件只需要大致相同的行数。再次从目录条目中读取文件大小。读取前N行(N应该很小但是文件的一些合理分数)来计算平均行长度。根据文件大小和预测的平均线长计算大致的行数。这假设线长遵循正态分布。如果没有,请调整您的方法以随机采样线(使用seek()或类似的东西)。在获得平均值后回滚文件,然后根据预测的行长度将其拆分。
两次读取文件。第一次计算行数。第二次将文件拆分成必要的部分。
编辑:使用shell脚本(根据您的评论),#2的随机版本将很难,除非您编写了一个小程序来为您执行此操作。您应该能够使用ls -l
来获取文件大小,wc -l
来计算确切的行数,head -nNNN | wc -c
来计算平均线长。
答案 6 :(得分:0)
这是一个带有变量的单行
file=onepiece.log; nsplit=5; len=$(wc -l < $file); split -l$(($len/$nsplit)) "$file" "$file.split" -da 4