LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   sed - replace alternate occurrences (on different lines) (https://www.linuxquestions.org/questions/programming-9/sed-replace-alternate-occurrences-on-different-lines-875259/)

gazzatav 04-15-2011 08:08 PM

sed - replace alternate occurrences (on different lines)
 
I'm trying to process a postscript file and I want to change alternate pages by finding the string '%%EndPageSetup' (and then adding a line after it).

I've tried using sed with labels and a branching program to ignore the odd occurrences and process the even ones. In the code below I tried searching for the first and ignoring it by jumping to next and processing it and then to the next odd page and so on.

My logic is obviously flawed here as it doesn't work but I've tried the following:

Code:

#!/bin/bash
sed -e '/%%EndPageSetup/{
b even
:odd
/%%EndPageSetup/ b even
:even
s/%%EndPageSetup/%%EndPageSetup++/ b odd}' filename.ps > newfile.ps

Any help appreciated.

grail 04-16-2011 02:33 AM

Well I am not sure sed is the right tool here as it doesn't really do counting as such.
Maybe awk can help:
Code:

awk '/%%EndPageSetup/{++a}!(a%2){sub(/%%EndPageSetup/,"&++")}1' filename.ps > newfile.ps

crts 04-16-2011 05:01 AM

Hi,

grail is right. Whenever it comes to tasks that require counting, 'sed' would not be the first tool of choice. The commands can get quite obfuscated.
However, this is one of the reasons I still like to think about possible sed solutions every now and then; it makes you think "out of the box" - even from a programmer's point of view.
Since you did not provide some representative sample data I had to guess - hope I guessed right:
Code:

%%startPageSetup
some stuff
%%EndPageSetup
%%startPageSetup
some stuff
%%EndPageSetup
%%startPageSetup
some stuff
%%EndPageSetup
%%startPageSetup
some stuff
%%EndPageSetup
%%startPageSetup
some stuff
%%EndPageSetup
%%startPageSetup
some stuff
%%EndPageSetup

And here is how you could process the above sample:
Code:

sed -r '/%%EndPageSetup/ {x;/%%EndPageSetup[[:blank:]]*$/ {s/(%%EndPageSetup).*/\1++/;h;b};g}' file

gazzatav 04-16-2011 09:31 AM

Thanks, both of those solutions work perfectly. That is exactly what I wanted. I can now process a postscript file with psbook to obtain signatures (groups of pages) and then move alternate pages out from the gutter as below (to provide a bit more context).

Code:

...
%%EndPageSetup
...
%%EndPageSetup
42 0 translate
...
%%EndPageSetup
...
%%EndPageSetup
42 0 translate

I shall have to read up more on awk and sed. Just for my better understanding: In the awk solution is the 'a' variable initialized with the 1 after the brace? In the sed solution is the 'b' command still a branching instruction? If so where does it branch to?

Thanks again.

grail 04-16-2011 10:20 AM

All variables in awk are set to 0 or empty before first invocation. This might help with the 'b' in sed.

gazzatav 04-16-2011 11:46 AM

I see, thanks, I'd read that to get my original attempt but missed that b on its own branches to the end of the script.


All times are GMT -5. The time now is 07:01 PM.