Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Awk or Sed ?

Status
Not open for further replies.

butterfm

Programmer
Feb 15, 2002
132
GB
Hi,

I'm struggling a bit with the following problem. I've tried awk and sed but can't get a solution.

I have a file containing text similar to the following (although I have cut bits out to fit it on this page)

NOT NULL, "PAGEHEIGHT" NUMBER(10, 0) NOT NULL) PCTFREE
40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 20480 NEXT
1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1
REM FREELIST GROUPS 1) TABLESPACE "FIN_CODAT" ;
REM ... 2 rows
CONNECT CUST_TEST;
CREATE UNIQUE INDEX "CUST_TEST"."OAS_ASM_INDEX1" ON "OAS_ASM" ("CODE" )
PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (INITIAL 20480 NEXT 20480
MINEXTENTS 1 MAXEXTENTS 2147483645 ;

What I need to do it replace the text, accross multiple lines, between the word "PCTFREE" and the next occuring ";" with another string, although I would want to keep semi colon ";"

e.g. Replacing the text with the word DOG would give me

NOT NULL, "PAGEHEIGHT" NUMBER(10, 0) NOT NULL) DOG ;
REM ... 2 rows
CONNECT CUST_TEST;
CREATE UNIQUE INDEX "CUST_TEST"."OAS_ASM_INDEX1" ON "OAS_ASM" ("CODE" )
DOG ;

I have managed this with sed when the text I want to replace only spans 2 lines but not when it spans more than 2 lines.

Any help with this would be greatly appreciated.

Thanks, Matt.
 
is it all on one line? or is it broken like the example you gave above?
 
I'm afraid it's broken like the example above.

Matt.
 
you might be better using something like perl, reading the whole file into an object, and doing a match that can span multiple lines.

another alternative is that you could (using sed) join all lines together that have 'PCTFREE' in them that don't end with ';', then replace everything from 'PCTFREE' to ';'

hmm, just thought you could probably turn on a flag when you see PCTFREE, replace PCTFREE (and beyond on that line) with your text, and ignore all lines until you find a ';'

can do that in both awk and sed...

Code:
nawk '
{show=semi}
BEGIN {show=1; semi=0}
/;/ {show=1}
/PCTFREE/{
    if (index($0,";") == 0) semi=0;
    sub("PCTFREE.*$", "DOG;");
}
show==1 {print}' < filename

seems to work in awk ... sure there must be a nicer way to get around the index bit, and make it smaller, but it works :)
 
actually not quite ...
Code:
nawk '
BEGIN {show=1; semi=1}
{show=semi}
/;/ {show=1}
/PCTFREE/{
    if (index($0,&quot;;&quot;) == 0) semi=0;
    sub(&quot;PCTFREE.*$&quot;, &quot;DOG;&quot;);
}
show==1 {print}' < filename

need to set semi to 1 at the beginning, otherwise all lines leading up to the first colon are ommitted :)
 
Thanks for your help Jad.

Much appreciated.

Matt.
 
umm ... the '
Code:
/;/ {show=1}
' should have been '
Code:
/;/ {semi=1}
'

oops ... don't you just love cut and paste :)
 
Hi,

Really want sed ? Try this sed script file

:jump
/PCTFREE[^;]*$/{
N
s/PCTFREE\(.*\)\n\(.*\)/PCTFREE\1 \2/
t jump
}
s/PCTFREE.*;$/DOG;/

 
Still wonder why I wrote an unreadable &quot;s/PCTFREE\(.*\)\n\(.*\)/PCTFREE\1 \2/&quot; instead of simple &quot;s/\n//&quot; ...
 
all of our examples assume that the semi-colon is the last thing on the line, and that there is never more than 1 semi-colon on a line.

since it looks like sql coding, anything after a semi-colon wouldn't be alowed, so it should never occur ... :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top