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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Find and replace with incremental value. 1

Status
Not open for further replies.

flavioweb

Technical User
Nov 28, 2011
7
IT
Suppose i have this code

---
bcc L_BRS_($4593)_($455E)

nop
nop
nop

L_BRS_($4593)_($455E)

bcc L_BRS_($4594)_($455F)

nop
nop
nop

L_BRS_($4594)_($455F)
---

I want to replace "L_BRS_($4593)_($455E)" with "lbrs001" (bot in single line and where line start with "bcc") and same with other "L_BRS".
At the end the code should look like:
---
bcc lbrs001

nop
nop
nop

lbrs001

bcc lbrs002

nop
nop
nop

lbrs002
---

I also need that the script "autodetect" the values between brachets of "L_BRS_($4593)_($455E)" and change all other of them in all text with the same value.
So "L_BRS_($4593)_($455E)" becomes lbrs001 in all text,
"L_BRS_($4594)_($455f) brcomes lbrs002 in all text... an so on.

Whit this:
awk 'BEGIN { rval=1000 } /L_BRS_/{gsub(/L_BRS_(.*)_(.*)/,"lbrs"rval,$0); rval++;} {print $0}' test.txt

i achieve this:

---
bcc lbrs1000

nop
nop
nop

lbrs1001

bcc lbrs1002

nop
nop
nop
bcc lbrs1000

nop
nop
nop

lbrs1001

bcc lbrs1002

nop
nop
nop

lbrs1003

lbrs1003
---
but isn't what i mean.
"1000" and "1001" should be the same.
"1002" and "1003" should be "1000"+1 and the same.

Someone can help me?
 
Hi

Separate the replacing and the incrementing.

The easiest is to increment only when the 1[sup]st[/sup] field is "bcc", then use the same rval for all subsequent replacements. This imposes a small change in setting the initial value too :
Code:
awk 'BEGIN [teal]{[/teal] rval[teal]=[/teal][purple][highlight]999[/highlight][/purple] [teal]}[/teal] [highlight][navy]$1[/navy][teal]==[/teal][green][i]"bcc"[/i][/green][teal]{[/teal][/highlight]rval[teal]++[/teal][highlight][teal]}[/teal][/highlight] [fuchsia]/L_BRS_/[/fuchsia][teal]{[/teal][COLOR=chocolate]gsub[/color][teal]([/teal][fuchsia]/L_BRS_(.*)_(.*)/[/fuchsia][teal],[/teal][green][i]"lbrs"[/i][/green]rval[teal],[/teal][navy]$0[/navy][teal])[/teal][teal]}[/teal] [teal]{[/teal][COLOR=chocolate]print[/color] [navy]$0[/navy][teal]}[/teal]' test.txt
Tested with [tt]gawk[/tt] and [tt]mawk[/tt].

Next time please post your code between [tt][ignore]
Code:
[/ignore][/tt] and [tt][ignore]
[/ignore][/tt] TGML tags.


Feherke.
 
Ok.
Sorry for the missed tags...

However, i understand the concept of your modify, and it fit perfectly with the few lines i posted here.

But i need to use it on a more complicated scenario.

Precisely, somethings like:

Code:
;----------------------------------
L_BRS_($0FF7)_($0FE8) OK
;----------------------------------
	JSR L_JSR_($0E6F)_($0FF7) OK
	LDA $B1 
	BNE L_BRS_($0FE2)_($0FFC) OK
	LDA $B0 
	BNE L_BRS_($0FE2)_($1000) OK
	DEC $A5 
	LDA $A5 
	BNE L_BRS_($0FEA)_($1006) OK
	LDX #$00
;----------------------------------
L_BRS_($100A)_($1010) OK
;----------------------------------
	PLA 
	STA $A6,X 
	INX 
	CPX #$04
	BNE L_BRS_($100A)_($1010) OK
;----------------------------------

L_BRS_($1012)_($0FA4) OK
;----------------------------------
	LDX #$00
;----------------------------------
L_BRS_($1014)_($101A) OK
;----------------------------------
	PLA 
	STA $A6,X 
	INX 
	CPX #$0A
	BNE L_BRS_($1014)_($101A) OK
	LDA $A5 
	BNE L_BRS_($102B)_($101E) OK
	LDA $94 
	STA $B0 
	LDA $95 
	STA $B1

With "bcc" can also be "bne, beq, bcs" bewfore L_BRS_... label.

And the bne/bcc/bcs/beq can be after the respective line with only "label" L_BRS_...

The better thing to do is (at least I think so, but may be the idea most wrong in the world) to check (match?) for L_BRS_(xxxxx)_(xxxxx) from top to bottom of the file, and, independently if the first finded was "only on line" or after bcc etc..., replace all others L_BRS according to "counter", so lbrs001, lbrs002, and so on...

Or you have another better idea?
 
Hi

Sounds like a double-pass solution would fit best ( note the input file name passed twice ) :
Code:
awk 'BEGIN[teal]{[/teal]rval[teal]=[/teal][purple]1000[/purple][teal]}[/teal][blue]FNR[/blue][teal]==[/teal][blue]NR[/blue][teal]{[/teal][b]if[/b][teal]([/teal][fuchsia]/L_(BRS|JSR)_/[/fuchsia][teal])[/teal][teal]{[/teal][COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/.*L_(BRS|JSR)_/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal]);[/teal][COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/ .*/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal]);[/teal][b]if[/b][teal](!([/teal][navy]$0[/navy] [teal]in[/teal] tag[teal]))[/teal]tag[teal][[/teal][navy]$0[/navy][teal]]=[/teal]rval[teal]++[/teal][teal]}[/teal][COLOR=chocolate]next[/color][teal]}[/teal] [fuchsia]/L_(BRS|JSR)_/[/fuchsia][teal]{[/teal]s[teal]=[/teal][navy]$0[/navy][teal];[/teal][COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/.*L_(BRS|JSR)_/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal],[/teal]s[teal]);[/teal][COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/ .*/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal],[/teal]s[teal]);[/teal][COLOR=chocolate]gsub[/color][teal]([/teal][fuchsia]/L_(BRS|JSR)_[^ ]*_[^ ]*/[/fuchsia][teal],[/teal][green][i]"lbrs"[/i][/green]tag[teal][[/teal]s[teal]],[/teal][navy]$0[/navy][teal])[/teal][teal]}[/teal][purple]1[/purple]' test.txt test.txt

Feherke.
 
Wow !

I need to check a little bit the output, but your code seems work like a charm!

Can you explain me how this -line- of code work?

Tnx a lot !!!
 
Hi

Not necessarily a line.
Code:
BEGIN [teal]{[/teal]                      [gray]# before processing[/gray]
  rval[teal]=[/teal][purple]1000[/purple]                  [gray]# initialize the variable[/gray]
[teal]}[/teal]
[gray]# this block will be executed only while reading the file the first time[/gray]
[blue]FNR[/blue][teal]==[/teal][blue]NR[/blue] [teal]{[/teal]                    [gray]# if current file's record is the same as overall record [/gray]
  [b]if[/b] [teal]([/teal][fuchsia]/L_(BRS|JSR)_/[/fuchsia][teal])[/teal] [teal]{[/teal]      [gray]# if $0 contains L_BRS or L_JSR_[/gray]
    [COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/.*L_(BRS|JSR)_/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal])[/teal] [gray]# remove that prefix and whatever is before that[/gray]
    [COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/ .*/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal])[/teal]            [gray]# remove anything after the first space[/gray]
    [b]if[/b] [teal](!([/teal][navy]$0[/navy] [teal]in[/teal] tag[teal]))[/teal]        [gray]# if the remaining string is not in array tag[/gray]
      tag[teal][[/teal][navy]$0[/navy][teal]]=[/teal]rval[teal]++[/teal]         [gray]# add it as key with value of rval[/gray]
  [teal]}[/teal]
  [COLOR=chocolate]next[/color]                       [gray]# continue with the next input record, skip remaining code[/gray]
[teal]}[/teal]
[gray]# this block will be executed only while reading the file the second time[/gray]
[fuchsia]/L_(BRS|JSR)_/[/fuchsia] [teal]{[/teal]             [gray]# if $0 contains L_BRS or L_JSR_[/gray]
  s[teal]=[/teal][navy]$0[/navy]                       [gray]# make a copy of $0[/gray]
  [COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/.*L_(BRS|JSR)_/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal],[/teal]s[teal])[/teal] [gray]# remove the prefix and whatever is before that[/gray]
  [COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/ .*/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal],[/teal]s[teal])[/teal]            [gray]# remove anything after the first space[/gray]
  [COLOR=chocolate]gsub[/color][teal]([/teal][fuchsia]/L_(BRS|JSR)_[^ ]*_[^ ]*/[/fuchsia][teal],[/teal][green][i]"lbrs"[/i][/green]tag[teal][[/teal]s[teal]])[/teal] [gray]# replace the L_*_ thing with the rval number we saved to it earlier[/gray]
[teal]}[/teal]
[purple]1[/purple]                            [gray]# always do the default action ( print $0 )[/gray]
By the way, the double-pass solution is needed if the sequence number has to be incremented not on first occurrence, but on another one and that would change the order. But as that part was not clear from your updated request, I only implemented the solution and let the condition to be added later.

In case the sequence has to be incremented always on the first occurrence, then the double-pass is not needed :
Code:
awk 'BEGIN[teal]{[/teal]rval[teal]=[/teal][purple]1000[/purple][teal]}[/teal][fuchsia]/L_(BRS|JSR)_/[/fuchsia][teal]{[/teal]s[teal]=[/teal][navy]$0[/navy][teal];[/teal][COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/.*L_(BRS|JSR)_/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal],[/teal]s[teal]);[/teal][COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/ .*/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal],[/teal]s[teal]);[/teal][b]if[/b][teal](!([/teal]s [teal]in[/teal] tag[teal]))[/teal]tag[teal][[/teal]s[teal]]=[/teal]rval[teal]++;[/teal][COLOR=chocolate]sub[/color][teal]([/teal][fuchsia]/ .*/[/fuchsia][teal],[/teal][green][i]""[/i][/green][teal],[/teal]s[teal]);[/teal][COLOR=chocolate]gsub[/color][teal]([/teal][fuchsia]/L_(BRS|JSR)_[^ ]*_[^ ]*/[/fuchsia][teal],[/teal][green][i]"lbrs"[/i][/green]tag[teal][[/teal]s[teal]],[/teal][navy]$0[/navy][teal])[/teal][teal]}[/teal][purple]1[/purple]' test.txt


Feherke.
 
I've tested all your 2 solutions, and seem both works for my purpose.

test code used:
Code:
L_BRS_($4593)_($455E)

nop
nop
nop
nop
bne L_BRS_($4593)_($455E)
nop
nop
nop
beq L_BRS_($4593)_($455E)
nop
nop
nop
bcc L_BRS_($4593)_($455E)


bcc L_BRS_($4594)_($455F)
nop
nop
bcs L_BRS_($4594)_($455F)
nop
nop
nop
bcc L_BRS_($4594)_($455F)

L_BRS_($4594)_($455F)
nop
nop
nop
bcc L_BRS_($4593)_($455E)

writed to have "labels" before and after "bcc/beq/bne", so we can check if they are -relabeled- correctly. Notice the last one, pointing to the first.

Result with 2 pass:
Code:
lbrs1000

nop
nop
nop
nop
bne lbrs1000
nop
nop
nop
beq lbrs1000
nop
nop
nop
bcc lbrs1000


bcc lbrs1001
nop
nop
bcs lbrs1001
nop
nop
nop
bcc lbrs1001

lbrs1001
nop
nop
nop
bcc lbrs1000

Result with 1 pass:
Code:
lbrs1000

nop
nop
nop
nop
bne lbrs1000
nop
nop
nop
beq lbrs1000
nop
nop
nop
bcc lbrs1000


bcc lbrs1001
nop
nop
bcs lbrs1001
nop
nop
nop
bcc lbrs1001

lbrs1001
nop
nop
nop
bcc lbrs1000

Exactly the same!

So the double-pass solution isn't needed.

However, thank a lot for your explanation.
Today i've learned some new.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top