【问题标题】:copy everything before the first blank line复制第一个空行之前的所有内容
【发布时间】:2016-03-19 20:08:11
【问题描述】:
我有一个文件,其中包含几个由空行分隔的文本块。例如:
block1
block1
block2
block3
block3
我需要一个使用 sed、awk 或 Perl 的解决方案来定位第一个空行并将前一个块重定向到另一个文件,依此类推,直到文件结束。
我在 sed 中有这个命令可以定位第一个块,而不是其余的:
sed -e '/./!Q'
有人可以帮我吗?
【问题讨论】:
标签:
perl
shell
awk
sed
grep
【解决方案1】:
这可能对你有用(GNU csplit 和 sed):
csplit -qf uniqueFileName file '/^$/' '{*}' && sed -i '/^$/d' uniqueFileName*
或者如果你想使用默认值:
csplit -q file '/^$/' '{*}' && sed -i '/^$/d' xx*
用途:
tail -n+1 xx* # to check the results
【解决方案2】:
考虑到block之间的几个空字符串
awk '/./{if(!L)++C;print>"Out"C".txt"}{L=$0!~/^$/}' YourFile
Sed 不允许不同的外部文件(实际上是未指定数量)作为输出
【解决方案3】:
在 Perl 中的另一种方法:
#!/usr/bin/perl
use strict;
use warnings;
# store all lines in $data
my $data = do { local $/; <DATA> };
my @blocks = split /\n\n/, $data;
my $n = 0;
write_to_file( 'file' . ++$n, $_ ) for @blocks;
sub write_to_file {
my $file = shift;
my $data = shift;
open my $fh, '>', $file or die $!;
print $fh $data;
close $fh;
}
__DATA__
block1
block1
block2
block3
block3
【解决方案4】:
这是我在 Perl 中的解决方案:
#!/usr/bin/perl
use strict;
use warnings;
my $n = 0;
my $block = '';
while (<DATA>) { # line gets stored in $_
if (/^\s*$/) { # blank line
write_to_file( 'file' . ++$n, $block );
$block = '';
} else {
$block .= $_;
}
}
# Write any remaining lines
write_to_file( 'file' . ++$n, $block );
sub write_to_file {
my $file = shift;
my $data = shift;
open my $fh, '>', $file or die $!;
print $fh $data;
close $fh;
}
__DATA__
block1
block1
block2
block3
block3
输出:
$ grep . file*
file1:block1
file1:block1
file2:block2
file3:block3
file3:block3
【解决方案5】:
这是awk:
$ awk 'BEGIN{file="file"++cont}/^$/{file="file"++cont;next}{print>file}' infile
结果
$ cat file1
block1
block1
$ cat file2
block2
$ cat file3
block3
block3
【解决方案6】:
这是 Perl 中的解决方案
open( my $fh, '<', '/tmp/a.txt' ) or die $!;
{
## record delimiter
local $/ = "\n\n";
my $count = 1;
while ( chomp( my $block = <$fh> ) ) {
open( my $ofh, '>', sprintf( '/tmp/file%d', $count++ ) ) or die $!;
print {$ofh} $block;
close($ofh);
}
}
close($fh);
【解决方案7】:
试试这条线:
awk -v RS="" '{print > "file"++c".txt"}' input
它将生成file1...n.txt