Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to put remove certain line breaks in a file
    primarykey
    data
    text
    <p>I have a file which contains about 70,000 records which is structured roughly like this:</p> <pre><code>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... </code></pre> <p><strong>EDIT 1: Every record thus starts with a column of numbers and ends with a blank line. Before this blank line most records have a <code>+Fieldname5</code> and one or more <code>-Content</code> lines.</strong></p> <p>What I would like to do is to merge all multi-line entries into one line while replacing the leading minus-character by a space <strong>except</strong> those pertaining to the last field (i.e. Fieldname5 in this case).</p> <p>it should look like this:</p> <pre><code>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... </code></pre> <p>what i have now is this (adapted from <a href="https://stackoverflow.com/questions/1523846/how-can-i-print-a-matching-line-one-line-immediately-above-it-and-one-line-immed/1523898#1523898">this answer</a>):</p> <pre><code>use strict; use warnings; our $input = "export.txt"; our $output = "export2.txt"; open our $in, "&lt;$input" or die "$!\n"; open our $out, "&gt;$output" or die "$!\n"; my $this_line = ""; my $new = ""; while(&lt;$in&gt;) { my $last_line = $this_line; $this_line = $_; # if both $last_line and $this_line start with a "-" do the following: if ($last_line =~ /^-.+/ &amp;&amp; $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); </code></pre> <p>but there are 2 problems with this:</p> <ul> <li><p>It correctly prints out the joined line but then still prints out the second line e.g.</p> <p>+Fieldname2 -Content Content Content -Content</p></li> </ul> <p>So how can I make the script only output the joined line?</p> <ul> <li>It only works on two lines at a time, while some of the multi-line entries have up to fourty lines. </li> </ul> <p><strong>EDIT 2:</strong> My question is thus how to do the following:</p> <ol> <li>Read in a file line by line and write it to an output file</li> <li>When a multi-line section appears read and process it in one go, replacing <code>\n-</code> by <code></code><strong>, except if it belongs to a given fieldname (e.g. <code>Fieldname5</code>).</strong></li> <li>Return to reading and writing each line again until another multi-line block appears</li> </ol> <p><strong>EDIT 3:</strong> It worked! I just added another conditional at the beginning: use strict; use warnings;</p> <pre><code>our $input = "export.txt"; our $output = "export2.txt"; open our $in, "&lt;$input" or die "Kann '$input' nicht finden: $!\n"; open our $out, "&gt;$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 (&lt;$in&gt;) { 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 &amp;&amp; /^-/) { # 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); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload