我有一个包含大约 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...
因此,每条记录都以一列数字开始,以空行结束。在此空行之前,大多数记录都有一个
+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...
我现在拥有的是这个(改编自这个答案):
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 -内容内容 内容 -内容
那么如何让脚本只输出连接的行呢?
我该如何执行以下操作?
\n-
替换为
,除非它属于给定的字段名称(例如,Fieldname5
)。成功了!我只是在开头添加了另一个条件:
use strict;
use warnings;
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);
假设唯一以“-”开头的行是这些多行部分,您可以这样做...
# Open $in and $out as in your original code...
my $insideMultiline = 0;
my $multilineBuffer = "";
LINE:
while (<$in>) {
if (/^-/) {
chomp;
if ($insideMultiline) {
s/^-/ /;
$multilineBuffer .= $_;
}
else {
$insideMultiline = 1;
$multilineBuffer = $_;
}
next LINE;
}
else {
if ($insideMultiline) {
print $out "$multilineBuffer\n";
$insideMultiline = 0;
$multilineBuffer = "";
}
print $out $_;
}
}
至于嵌入的子问题(“除了与最后一个字段相关的问题”),我需要有关文件格式的更多详细信息才能做到这一点。看起来好像有一个空行将字段和内容集彼此分隔开,但这在描述中并不是 100% 清楚。不过,上面的代码应该可以满足您在底部列出的要求。