Alby
Alby

Reputation: 5742

Using Perl Regex Multiline to reformat file

I have the file with the following format:

(Type 1 data:1)
B
B
(Type 1 data:2)
B
B
B
(Type 1 data:3)
B
..

Now I want to reformat this file so that it looks like:

(Type 1 data:1) B B
(Type 1 data:2) B B B
(Type 1 data:3) B
...

My approach was to use perl regex in command line,

cat file | perl -pe 's/\n(B)/ $1/smg' 

My reasoning was to replace the new line character with space. but it doesn't seem to work. can you please help me? Thanks

Upvotes: 3

Views: 869

Answers (3)

Brad Gilbert
Brad Gilbert

Reputation: 34120

If the only place that ( shows up is at the beginning of where you want your lines to start, then you could use this command.

perl -l -0x28 -ne's/\n/ /g;print"($_"if$_' < file
  • -l causes print to add \n on the end of each line it prints.
  • -0x28 causes it to split on ( instead of on \n.
  • -n causes it to loop on the input. Basically it adds while(<>){chomp $_; to the beginning, and } at the end of what ever is in -e.
  • s/\n/ /g
  • print "($_" if $_ The if $_ part just stops it from printing an extra line at the beginning.

Upvotes: 4

Steve C
Steve C

Reputation: 647

The -p reads a line at a time, so there is nothing after the "\n" to match with.

perl -pe 'chomp; $_ = ($_ =~ /Type/) ? "\n".$_ : " ".$_'

this does almost what you want but puts one extra newline at the beginning and loses the final newline.

Upvotes: 5

Lumi
Lumi

Reputation: 15264

It's a little more involved as -n and -p fit best for processing one line at a time while your requirement is to combine several lines, which means you'd have to maintain state for a while.

So just read the entire file in memory and apply the regex like this:

perl -lwe ^
"local $/; local $_ = <>; print join q( ), split /\n/ for m/^\(Type [^(]*/gsm"

Feed your file to this prog on STDIN using input redirection (<).

Note this syntax is for the Windows command line. For Bash, use single quotes to quote the script.

Upvotes: 1

Related Questions