我有一个如下所示的文件:
1weather dnsndjsdn
2nm bdbdb bdbdbdbdnnd
3gfdu hsihdishdis
5
1hdohdsohsoihssodhoishs
2nfdksnkdsnfsdsjndkdj
3kjdscdskndskjndndsdsdsd
5
同样,我在一个文件中可能有近 20,000 个块 1 到块 5
我需要计算块 1 到块 5 的数量,然后将文件拆分为较小的 4 个文件。前 3 个文件可能具有相同数量的块 1 到块 5,最后的较小文件可能具有剩余的块 1 到块 5。
假设我有五个块 1 到块 5
1weather dnsndjsdn
2nm bdbdb bdbdbdbdnnd
3gfdu hsihdishdis
5
1hdohdsohsoihssodhoishs
2nfdksnkdsnfsdsjndkdj
3kjdscdskndskjndndsdsdsd
5
1weather dnsndjsdn
2nm bdbdb bdbdbdbdnnd
3gfdu hsihdishdis
5
1hdohdsohsoihssodhoishs
2nfdksnkdsnfsdsjndkdj
3kjdscdskndskjndndsdsdsd
5
1weather dnsndjsdn
2nm bdbdb bdbdbdbdnnd
3gfdu hsihdishdis
5
我将生成如下 4 个文件
文件一:
1weather dnsndjsdn
2nm bdbdb bdbdbdbdnnd
3gfdu hsihdishdis
5
文件2:
1hdohdsohsoihssodhoishs
2nfdksnkdsnfsdsjndkdj
3kjdscdskndskjndndsdsdsd
5
文件3:
1weather dnsndjsdn
2nm bdbdb bdbdbdbdnnd
3gfdu hsihdishdis
5
文件4:
1hdohdsohsoihssodhoishs
2nfdksnkdsnfsdsjndkdj
3kjdscdskndskjndndsdsdsd
5
1weather dnsndjsdn
2nm bdbdb bdbdbdbdnnd
3gfdu hsihdishdis
5
有人可以建议如何使用 Unix 脚本来实现这一点吗?
任何帮助深表感谢。
答案1
用 grep 吗?
grep -E '^1' < file_to_parse > blocks_1
grep -E '^2' < file_to_parse > blocks_2
grep -E '^3' < file_to_parse > blocks_3
grep -v -E '^1' | grep -v -E '^2' | grep -v -E '^3' < file_to_parse > other_blocks
未测试。
答案2
好的,那么 - 获取一些输入,将其分离5
,然后将这些块分成单独的文件?
实际上,在最后一个文件中添加“额外”比听起来要困难一些,因为您必须阅读整个文件第一的在你知道分布之前,但循环输出很容易:
- 打开4个文件句柄
- 将记录分隔符设置为
5
. - 迭代输入记录,根据“块”号选择文件句柄
$.
- 打印到那个fh
就像是:
#!/usr/bin/env perl
use strict;
use warnings;
my $num_files_to_write = 4;
use Data::Dumper;
my @filehandles;
for my $id ( 1..$num_files_to_write ) {
open ( my $fh, '>', "file_$id.txt" ) or die $!;
push @filehandles, $fh;
}
local $/ = '5';
while ( <> ) {
select $filehandles[$. % $num_files_to_write];
print;
}
foreach my $fh ( @filehandles ) {
close ( $fh );
}
注意 - 并不完全按照您想要的顺序排列,因为“第一个”块是零,但您的第一个文件编号是 1。这就像加/减一样简单$. + 1 % $num_files_to_write
。但这取决于您是否关心哪个文件得到什么,或者这是否只是一个划分的问题。