Computing.Net > Forums > Unix > Can I replace paragraphs using sed?

Can I replace paragraphs using sed?

Reply to Message Icon

Original Message
Name: may
Date: August 11, 2003 at 23:53:32 Pacific
Subject: Can I replace paragraphs using sed?
OS: Solaris
CPU/Ram: -
Comment:

Hi,
I have this problem and I wish to know is there an easy way to solve it?

I have a file containing in it couples of lines with a specific format (among many other lines).
The format of the couples look like that:
rocks 20
books 12

or:
rocks 32
books 7

etc..

the numbers follow rocks and books could be any numbers.

I want to get 4 numbers as parameters, and than to check these couples at the file for a match, if there is a match than the numbers of these certain couples at the file should be replace.

example:

the file a.txt starts here
the numbers
is it true
rocks 20
books 12
yes
I want to be there
rocks 12
books 20
rocks 65
books 17
why is it
rocks 20
books 12
so difficult
rocks 20
books 78
the file a.txt ends here

Now if I get the parameters : 20 12 100 200

than it means that I should look for the couples:
rocks 20
books 12
and change them to:
rocks 100
books 200

the file after the changes should look like that:

the file a.txt starts here
the numbers
is it true
rocks 100
books 200
yes
I want to be there
rocks 12
books 20
rocks 65
books 17
why is it
rocks 100
books 200
so difficult
rocks 20
books 78
the file a.txt ends here

Is it possible to use the sed command in order to search for a pattern of 2 lines with the first 2 numbers :
rocks 20
books 12

and than to replace them with the last 2 numbers?
rocks 100
books 200

I need to know is there a short easy way with sed or should I write scripts to solve that,

thanks for your help



Report Offensive Message For Removal


Response Number 1
Name: Frank
Date: August 12, 2003 at 00:44:05 Pacific
Reply: (edit)

Hi,

didn't know if I got it right, especially
because of the doble occurance of "rocks 20"
in your file, but based on your example the
ed script below will give the output.

/bin/ed a.txt - 1>/dev/null EOF
/$1
s/$1/$3
/$2
s/$2/$4
w
q
EOF

NO RISK no fun

Frank


Report Offensive Follow Up For Removal

Response Number 2
Name: James Boothe
Date: August 12, 2003 at 09:10:19 Pacific
Reply: (edit)

sed -e '$!N' \
    -e "/.*rocks $1.*\n.*books $2.*/ba" \
    -e '$!{P;D;}' \
    -e 'p;d' \
    -e :a -e "s/rocks $1/rocks $3/;s/books $2/books $4/" \
may.txt

That sed script traverses a file looking at two lines at a time: line1/line2, then line2/line3 etc.

If the current two lines do not qualify, the first of those is printed and deleted, and the next cycle appends the next line.

When it finds two lines that qualify, it branches to label "a" where the desired edits are done, and by default both of these lines are printed.

One problem is embedded-string hits. When changing "rocks 20" to "rocks 100", it would find "rocks 209" and change it to rocks 1009".  If those numbers actually terminate the line, then the sed command can search for "rocks 20$".


Report Offensive Follow Up For Removal

Response Number 3
Name: may
Date: August 13, 2003 at 23:57:32 Pacific
Reply: (edit)

Hi,
Thanks to both of you!
with the help of your scripts and some other help, I got the solution for my problem:

sed -f SedFile InputFile

SedFile:

/rocks 20$/{
N
/books 30$/{
s/rocks 20$\(.*\)books 30$/rocks 100\1books 200/
}
}

the only thing I am looking for now is how to pass the 4 numbers
as parameters to the script,
if you have any suggestion I will appreciate it.

Regards may


Report Offensive Follow Up For Removal

Response Number 4
Name: James Boothe
Date: August 14, 2003 at 07:23:06 Pacific
Reply: (edit)

I like your solution - more simple - not doing the join until encountering the first possible qualifying line.

That may work for your data, but there is a problem with that code. If you were to have:

I want to be there
rocks 20
rocks 20
books 30

your code would not change those last two lines because it was thrown off by that first "rocks 20" line.

The solution I posted earlier does not have that problem because it moves forward only one line at a time, looking at each set of two lines.

But if you are comfortable that you will not encounter that situation, then your solution will work for you. To input the variables, I would code the program in-line rather than with -f. You can use $1 $2 $3 $4 or feed these through variables like this:

#!/bin/sh

x=$1
y=$2
X=$3
Y=$4

sed "/rocks $x$/{
N
/books $y$/{
s/rocks $x\(.*\)books $y$/rocks $X\1books $Y/
}
}" InputFile

exit 0


Report Offensive Follow Up For Removal

Response Number 5
Name: may
Date: August 17, 2003 at 01:27:15 Pacific
Reply: (edit)

Thanks a lot it works perfectly!!!


Report Offensive Follow Up For Removal







Use following form to reply to current message:

   Name: From My Computing.Net Settings
 E-Mail: From My Computing.Net Settings

Subject: Can I replace paragraphs using sed?

Comments:

 


  Homepage URL (*): 
Homepage Title (*): 
         Image URL: 
 
Data Recovery Software




Have you ever used OpenOffice?

Yes, as my main suite.
Yes, occationally.
Yes, but only once.
No, never.


View Results

Poll Finishes In 5 Days.
Discuss in The Lounge