おおよそ次のような構造の約 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...
EDIT 1: したがって、すべてのレコードは数字の列で始まり、空白行で終わります。ほとんどのレコードには、この空白行の前に+Fieldname5
と 1 つ以上の-Content
行があります。
私がやりたいことは、最後のフィールド (この場合は Fieldname5) に関連するものを除いて、先頭のマイナス文字をスペースに置き換えながら、すべての複数行エントリを 1 行にマージすることです。
次のようになります。
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つの問題があります:
結合された行を正しく印刷しますが、それでも2行目を印刷します。
+Fieldname2 -コンテンツ コンテンツ コンテンツ -コンテンツ
では、スクリプトが結合された行のみを出力するようにするにはどうすればよいでしょうか?
- 一度に 2 行でしか機能しませんが、複数行のエントリの中には最大 40 行まであるものもあります。
編集2:私の質問は、次のことを行う方法です:
- ファイルを 1 行ずつ読み込み、出力ファイルに書き込みます
- 複数行のセクションが表示された場合は、指定されたフィールド名 (例: ) に属している場合を除き
\n-
、一度に読み取って処理し、 に置き換えます。Fieldname5
- 別の複数行ブロックが表示されるまで、各行の読み取りと書き込みに戻ります
編集3: うまくいきました!最初に別の条件を追加しました: use 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);