user3507732
user3507732

Reputation: 5

How to concatenate continuation lines in Perl?

I have a CSV file which contains strings like this:

ID1;banana
| apple
| oranges

and I want that every time there is a pipe at the beginning of the line, the string will be appended to the previous line, the output should be like this:

ID1;banana | apple | oranges

how can remove the newlines that precede a line begining with a pipe |?

Upvotes: 0

Views: 472

Answers (3)

Borodin
Borodin

Reputation: 126742

Is the string you show the value of a single CSV field? If so then you should be using Text::CSV to divide each line into fields (as its getline method is the simplest way to cope with data that contains embedded newlines) and you can use the substitution s/\n(?=\|)/ /g to change a newline into a space if it precedes a pipe character.

Here's an example

use strict;
use warnings;

use Text::CSV;

my $csv = Text::CSV->new({ binary => 1, eol => $/ });

while (my $row = $csv->getline(*DATA)) {
  s/\n(?=\|)/ /g for @$row;
  print "$_: $row->[$_]\n" for 0 .. $#$row;
  print "\n";
}

__DATA__
"ID1;banana
| apple
| oranges",f2,f3
g1,g2,g3

output

0: ID1;banana | apple | oranges
1: f2
2: f3

0: g1
1: g2
2: g3

If your circumstance is different from that then you need to explain.

Upvotes: 0

Miller
Miller

Reputation: 35208

In a hackish one liner, removing returns before pipes:

perl -ne '$s = do {local $/; <>}; $s =~ s/\n\|/ |/g; print $s' file.csv

Upvotes: 4

Magnus
Magnus

Reputation: 11456

Instead of trying to backspace/erase what's already been printed, you could instead only print the carriage return when a | isn't the first char:

perl -n -e 'chomp; /^\s*\|/? print " $_":  print "\n$_" ' yourfile.txt

Upvotes: 1

Related Questions