The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
.
google unix.com



Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
how to insert text between lines of an existing file using perl madhul2002 Shell Programming and Scripting 3 01-19-2009 03:08 AM
Insert Title To Each Lines tqlam Shell Programming and Scripting 2 11-05-2008 10:07 PM
Insert lines between delimiters BMDan Shell Programming and Scripting 2 09-04-2008 06:04 PM
insert multiple lines into a file c0mrade Shell Programming and Scripting 12 09-04-2008 05:04 PM
How to count lines - ignoring blank lines and commented lines kthatch UNIX for Dummies Questions & Answers 6 05-25-2007 02:21 AM

Reply
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Bulgarian Greek Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 06-09-2009
ejdv ejdv is offline
Registered User
  
 

Join Date: Nov 2007
Posts: 46
Question [Perl] Insert lines before lines.

Hi,

New problem, or challenge as they prefer in the US.

I need to insert some lines in a file before certain other lines.
To make it more clear:

Original file:


Code:
aaaa
bbbbb
ccccc
ddddd
bbbbb
fffff
ggggg

Now I want to insert the line "NEW_NEW_NEW" when I match "fffff", but I want it to be before the 5th line with "bbbbb".
Like this:


Code:
aaaa
bbbbb
ccccc
ddddd
NEW_NEW_NEW
bbbbb
fffff
ggggg

Notice that the line with "bbbbb" is more times present, so I cannot use that as search string.
It is the last present line with "bbbbb" though, perhaps that helps.

I tried:


Code:
$file_to_update = "test.txt";
open (FILE_TO_UPDATE, "<$file_to_update");
my @lines = <FILE_TO_UPDATE>;
close (FILE_TO_UPDATE);

open (FILE_TO_UPDATE, ">$file_to_update");
for (@lines) {
  if ($_ =~ m/fffff/) {
  print FILE_TO_UPDATE "NEW_NEW_NEW";
  }
  print FILE_TO_UPDATE;
}
close (FILE_TO_UPDATE);

But then I get the wrong order:


Code:
aaaa
bbbbb
ccccc
ddddd
bbbbb
NEW_NEW_NEW
fffff
ggggg

Anyone with some ideas ?

E.J.
  #2 (permalink)  
Old 06-10-2009
radoulov's Avatar
radoulov radoulov is offline Forum Staff  
addict
  
 

Join Date: Jan 2007
Location: Варна, България / Milano, Italia
Posts: 2,928
Quote:
[...] It is the last present line with "bbbbb" though, perhaps that helps.

Code:
perl -0pe'  
  s/bbbbb(?!.*bbbbb)/NEW_NEW_NEW\n$&/s
  ' infile

  #3 (permalink)  
Old 06-10-2009
ejdv ejdv is offline
Registered User
  
 

Join Date: Nov 2007
Posts: 46
Quote:
Originally Posted by radoulov View Post
Code:
perl -0pe'  
  s/bbbbb(?!.*bbbbb)/NEW_NEW_NEW\n$&/s
  ' infile
Thanks for the one-liner.
For this example it works, but you understand it is part of a bigger universe :-)
And I am having trouble incorporating it in the example code.
Not to mention that I do not understand the wizardry in your one-liner.
I understand it is a conditional substitute, but what is the $ and the & doing for example ?

But let me make the problem a bit more real life.

Here is the test.txt data file (edited for the forum).
It is a ksh script and this is how it comes after an installation.
I need to modify it and I would like to have this modification done by a script.


Code:
if [ -f $topload_inprogress ]
then
		blahlblah
		rm $inprogress
		exit 1
fi 

if [ ! -f $params ]
then
	blahlblah
	rm $inprogress
	exit 1
fi 

if(($?==1))
then 
	blahlblah
	rm $inprogress
	exit 1
fi

if [[ -f $ftp_fin ]]
then
	rm $ftp_fin
else
	blahlblah
	rm $inprogress
	exit 1
fi

files=`ls $CADATA/srcdata/$source/custom/BULK/after`
for name in $files
do
	blahlblah
done

rm $inprogress
$CAROOT/prog/ca_log_message TOPOLOGY_STAT "Finished the bulk ftp topology load of $source data source."
exit 0

I need to insert a block-text (6 lines) between last 'done' and the 'rm $inprogress'.

Can your "(?!.*bbbbb)" be of any help there ?

Greetings,

E.J.
  #4 (permalink)  
Old 06-10-2009
radoulov's Avatar
radoulov radoulov is offline Forum Staff  
addict
  
 

Join Date: Jan 2007
Location: Варна, България / Milano, Italia
Posts: 2,928
Can you use the pattern ^rm $inprogress (at the beginning of the line) as a marker?
Or perhaps its last occurrence?
Do you really need both patterns done .. rm $inprogress?
Why Perl? I suppose the task could be done with a lighter tool (e.g. sed).

Last edited by radoulov; 06-10-2009 at 12:50 PM..
  #5 (permalink)  
Old 06-10-2009
ejdv ejdv is offline
Registered User
  
 

Join Date: Nov 2007
Posts: 46
Quote:
Originally Posted by radoulov View Post
Can you use the pattern ^rm $inprogress (at the beginning of the line) as a marker?
Or perhaps its last occurrence?
Do you really need both patterns done .. rm $inprogress?
Why Perl? I suppose the task could be done with a lighter tool (e.g. sed).
The file comes like this, I have no control over it.
And if I have to "prepair" it manually, then I can make the text insert manually too.
But I don't want to.

The last "rm $inprogress" is at the end of the file, so it is the last occurrence.

The text-block needs to be between the last "done" and the last "rm $inprogress", that's a given.

I use Perl, because I need to make many more modifications in other files and I need to start things, stop things, etc.
Perl is perfect for this.
This is one of the many sub-routines in the script.
In fact I need to make 2 text-block insertions in this file and the second one has this problem I described.

If necessary I could call a sed command from within Perl, right ?
But I do not see why it could not be done with Perl.
Okay, I can't, but I am not the brightest Perl programmer around
Not yet.

Now I am thinking about counting the "done"s, printing all lines including the last "done". Then print my text-block and then print the last lines.
Or perhaps read 2 lines, test the 2nd line for "Finished the bulk ftp".
Print all lines until the test is true, print my test-block and print the last lines.
Something should be possible.

E.J.
  #6 (permalink)  
Old 06-10-2009
radoulov's Avatar
radoulov radoulov is offline Forum Staff  
addict
  
 

Join Date: Jan 2007
Location: Варна, България / Milano, Italia
Posts: 2,928
Quote:
Originally Posted by ejdv View Post
The file comes like this, I have no control over it.
And if I have to "prepair" it manually, then I can make the text insert manually too.
But I don't want to.

The last "rm $inprogress" is at the end of the file, so it is the last occurrence.

The text-block needs to be between the last "done" and the last "rm $inprogress", that's a given.
OK,
you can use something like this (you should add exception handling, of course):


Code:
#!/usr/bin/perl

use warnings;
use strict;

my ( $shellscript, $pattern ) = ( shift, 'rm \$inprogress' );

my $newcode = <<_NEWCODE_;
line1
line2
...
line6
_NEWCODE_

{
    local ( $^I, @ARGV, $/ ) = ( '', $shellscript );
    while (<>) {
        s/$pattern(?!.*$pattern)/$newcode\n$&/s;
        print;
    }
}

Quote:
I use Perl, because I need to make many more modifications in other files and I need to start things, stop things, etc.
Perl is perfect for this.
This is one of the many sub-routines in the script.
In fact I need to make 2 text-block insertions in this file and the second one has this problem I described.

If necessary I could call a sed command from within Perl, right ?
But I do not see why it could not be done with Perl.
You don't need to call sed from Perl
I'm not saying that you should not use Perl for this,
but that sed is sufficient for this task.
And yes, of course, if this is only one of the tasks and you have other code in Perl, you should do it all in Perl.
Reply

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 06:12 AM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0