LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Perl: how to replace blank lines in a file with given lines from another (http://www.linuxquestions.org/questions/programming-9/perl-how-to-replace-blank-lines-in-a-file-with-given-lines-from-another-940472/)

karamaz0v 04-18-2012 10:20 AM

Perl: how to replace blank lines in a file with given lines from another
 
Hi all,

I have two textfiles, one with N lines (N.dat), and other with a header and N blocks of data (block.dat) separated each with a blank line.

I want to insert each line from N.dat into each corresponding blank line in block.dat (also remove the header in the same process), i.e. I have

Code:

N.dat
1
2
3

Code:

block.dat
HEADER
HEADER

AAAA
BBBB
CCCC

AAAA
BBBB
CCCC

AAAA
BBBB
CCCC

and i want to obatin

Code:

1
AAAA
BBBB
CCCC
2
AAAA
BBBB
CCCC
3
AAAA
BBBB
CCCC


which would be one way to achive this with perl?

thanks,

danielbmartin 04-18-2012 10:37 AM

Do all blocks consist of three lines, or was that merely an accident of making a simple example? Are the "breaks" between blocks always a single blank line or possibly more than one blank line?

Daniel B. Martin

grail 04-18-2012 12:35 PM

Code:

awk '/^$/{getline < "N.dat"}1' block.dat

danielbmartin 04-18-2012 04:29 PM

Quote:

Originally Posted by grail (Post 4656359)
Code:

awk '/^$/{getline < "N.dat"}1' block.dat

Nitpick: OP wanted to discard the HEADER lines and you didn't do that. Should the awk be preceded by a grep? Can the awk be elaborated to ditch those HEADERs?

Daniel B. Martin

karamaz0v 04-18-2012 08:03 PM

thank for the replies,

the awk one liner works with my example but not with my real case, i'm looking at it.

About the header I can remove it before or after inserting the lines using something like
sed '1,xd'
for x number of header lines.

Daniel: all blocks consist of the same number of lines, more than 3 but always the same in a given block.dat file (also in the header i have that number) and each "break" is only a single blank line.

To go further, I also need to invert each block, i.e. obtain

Code:

1
CCCC
BBBB
AAAA
2
CCCC
BBBB
AAAA
3
CCCC
BBBB
AAAA

I asked for a perl option, because I have a fortran program to do this now, but for portability I'm trying to learn perl scripting, sorry if I'm asking too much, maybe I have to keep writing it and come back here posting a semi working script.
anyway, an awk one liner would be of great help also.

thank for your help.

karamaz0v 04-18-2012 09:23 PM

the problem with my real problem is that each break is not exactly a blank line, but a line with only a Single whitespace, for that reason the awk /^$/ pattern don't match those.
I solved that using previously
sed 's/^[ \t]*$//' filename
which will also convert every line containing tabs or more whitespaces to a "real" blank line.

After applying this sed command, the awk one liner works great, now I only need to know how to invert each block.

regards.

grail 04-19-2012 02:17 AM

As I would guess that the example data still looks nothing like the actual, I will leave the swapping of lines 1 and 3 to you (reference: http://www.gnu.org/software/gawk/man...e/index.html):
Code:

awk '/^ $/ && ++x{getline < "N.dat"}x' block.dat

karamaz0v 04-19-2012 05:23 AM

ok,
the actual example is almost the same (after converting blank lines to real blank with no whitspaces), only difference is the number of lines at each block is not 3, is around fifty always.
since my original question was answered I marked it as solved, i'll figure out how to do the inversion.

thanks.

grail 04-19-2012 06:48 AM

btw. The last solution accounts for the space on the line, ie no need to convert prior. You could also throw an asterisk in there so it can contain zero to many spaces and your covered :)


All times are GMT -5. The time now is 08:46 AM.