我有一个包含约70,000条记录,其大致结构像这样的文件:解决:如何把删除某些换行符在文件中
01499 1000642 4520101000900000
...more numbers...
104000900169
+Fieldname1
-Content
+Fieldname2
-Content
-Content
-Content
+Fieldname3
-Content
-Content
+Fieldname4
-Content
+Fieldname5
-Content
-Content
-Content
-Content
-Content
-Content
01473 1000642 4520101000900000
...more numbers...
编辑1:每记录由此开始与一列数字并以空行结束。在此空白行之前,大多数记录具有+Fieldname5
和一个或多个-Content
行。
我想这样做的是所有多行条目合并成一条线,而用空格代替领先负字符的情况除外那些与最后一个字段(即Fieldname5在这种情况下)。
它应该是这样的:
01499 1000642 4520101000900000
...more numbers...
104000900169
+Fieldname1
-Content
+Fieldname2
-Content Content Content
+Fieldname3
-Content Content
+Fieldname4
-Content
+Fieldname5
-Content
-Content
-Content
-Content
-Content
-Content
01473 1000642 4520101000900000
...more numbers...
什么,我现在是这样(改编自this answer):
use strict;
use warnings;
our $input = "export.txt";
our $output = "export2.txt";
open our $in, "<$input" or die "$!\n";
open our $out, ">$output" or die "$!\n";
my $this_line = "";
my $new = "";
while(<$in>) {
my $last_line = $this_line;
$this_line = $_;
# if both $last_line and $this_line start with a "-" do the following:
if ($last_line =~ /^-.+/ && $this_line =~ /^-.+/) {
#remove \n from $last_line
chomp $last_line;
#remove leading "-" from $this_line
$this_line =~ s/^-//;
#join both lines and print them to the file
$new = join(' ', $last_line,$this_line);
print $out $new;
} else {
print $out $last_line;
}
}
close ($in);
close ($out);
,但有2个问题是:
它正确打印出连接的行,但仍然打印出第二行,例如
+ Fieldname2 -content内容 内容 -content
那么,怎样才能让我的脚本只输出连接线?
- 它一次只能在两条线上工作,而一些多线条目有多达四十条线。
编辑2:我的问题是这样如何做到以下几点:通过线
- 读取文件中的行,并将其写入到输出文件
- 当多管路段出现读取并一次处理它,替换
\n-
,除非它属于给定的字段名称(例如
Fieldname5
)。 - 返回读取和写入一次的每一行,直到另一个多行数据块出现
编辑3: 它的工作!我刚刚在开头添加了另一个条件: 使用strict; 使用警告;
our $input = "export.txt";
our $output = "export2.txt";
open our $in, "<$input" or die "Kann '$input' nicht finden: $!\n";
open our $out, ">$output" or die "Kann '$output' nicht erstellen: $!\n";
my $insideMultiline = 0;
my $multilineBuffer = "";
my $exception = 0; # variable indicating whether the current multiline-block is a "special" or not
LINE:
while (<$in>) {
if (/^\+Fieldname5/) { # if line starts with +Fieldname5, set $exception to "1"
$exception = 1;
}
elsif (/^\s/) { # if line starts with a space, set $exception to "0"
$exception = "0";
}
if ($exception == 0 && /^-/) { # if $exception is "0" AND the line starts with "-", do the following
chomp;
if ($insideMultiline) {
s/^-/ /;
$multilineBuffer .= $_;
}
else {
$insideMultiline = 1;
$multilineBuffer = $_;
}
next LINE;
}
else {
if ($insideMultiline) {
print $out "$multilineBuffer\n";
$insideMultiline = 0;
$multilineBuffer = "";
}
print $out $_;
}
}
close ($in);
close ($out);
非常感谢!