У меня есть файл, который содержит около 70000 записей, который примерно так структурирован:
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...
что ятеперь есть это (адаптировано из этот ответ ):
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 Content -Content
Так как я могу сделать так, чтобы скрипт выводил только объединенную строку?
- Работает только на двух строках одновременно, в то время как некоторые многострочные записи имеют до сорока строк.
РЕДАКТИРОВАТЬ 2: Таким образом, мой вопрос состоит в том, как сделать следующее:
- Считать файл за строкой и записать его в выводfile
- Когда появляется многострочный раздел, прочитайте и обработайте его за один раз, заменив
\n-
на
, за исключением случаев, когда он принадлежит данному имени поля (например, Fieldname5
). - Вернуться к чтению и записи каждой строки снова, пока не появится другой многострочный блок
РЕДАКТИРОВАТЬ 3: Это сработало!Я просто добавил еще одно условие в начале: используйте строгий;используйте предупреждения;
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);