SED to replace exact match, not first occurrence.

Lets say I have file.txt:
(Product:Price:QuantityAvailable) (: as delimiter)
Chocolate:5:5
Banana:33:3

I am doing a edit/update function.
I want to change the Quantity Available, so I tried using the SED command to replace 5, but my Price which is also 5 is changed instead.
(for the Banana case, if I were to replace 3 with 5, my price will be 53 because it replaced the 3 which comes first)
Is there a way to only replace data within the Delimiter?
Or rather, how should I go about solving this?

Thanks in advance!

$ cat file1
(Product:Price:QuantityAvailable) (: as delimiter)
Chocolate:5:5
Banana:33:3

$ sed "/^Chocolate/ s/[^:]*$/14/" file1
(Product:Price:QuantityAvailable) (: as delimiter)
Chocolate:5:14
Banana:33:3

Other languages, like awl handle "delimeters" better than sed.

1 Like

Depending on how exactly you want to edit:
If you want to change all line having "Chocolate:5:5" to "Chocolate:5:10"

sed 's/Chocolate:5:5/Chocolate:5:10/'

OR change all lines "Banana:33:3" to "Banana:33:5"

sed 's/Banana:33:3/Banana:33:5/'

OR change line Banna pricers to 5 (whatever be the current price)

sed 's/Banana:\(.*\):\(.*\)/Banana:\1:5/'
1 Like

Thanks guys,
another question here. (Sorry, I just started learning bash programming last week)

but what if my data was like this:
Chocolate:12:12:12:12:12:12:12

say I want to replace the 4th 12 to 5 without changing the rest of the 12 infront of it? If I were to code it the way using start with Chocolate:12:12:12: and start replacing, wouldn't it be problematic if my files were to have alot data?
I'm not restricted to using SED, but restricted to using BASH.
Are there any suggestions?

Thanks alot.

Well, I never saw that question coming :wink: :smiley:

sed starts getting ugly when you try to do this stuff.

$ awk -F: '/^Chocolate/ {$4=5}1' OFS=: file1
Chocolate:12:12:5:12:12:12:12
1 Like

Really thanks and appreciate your fast reply!
I'll give the code a try later. (currently learning to do other functions)

Thanks again!

Not that ugly :slight_smile:

sed '/^Chocolate/s/[^:]*/5/5' file

(4th 12 is the fifth field, right?)

1 Like

You're right. I never remember that thing :smiley:

1 Like

yes, 4th 12 is fifth, but can you explain this code? I can't really understand it.

I understand the part sed '/^Chocolate/s
It means Start With Chocolate, and then substitute right?
What I don't understand is the [^:]*/5
The last part /5 means replace with 5 right?

As for $ awk -F: '/^Chocolate/ {$4=5}1' OFS=: file1
What does the "{$4=5}1" , the 1 means?

I'll give both codes a try later just to learn more.
Thanks!

:b:

sed '/^Chocolate/{/:/s/12/5/4}' inputfile > outfile

Change the last number (here) 4, according to the position of 12 you want to change

1 Like

It means on the line starting with Chocolate replace the first occurrence of the pattern with 5. The pattern is [^:], which means 0 or more occurrences () of any character that isn't ":"

---
@michael, that is equivalent to:

sed /^Chocolate/s/12/5/4 file

But then you would really use the content as the fields instead of just the position. That would really change the 4th occurrence of 12 irrespective of what column it is in, or what string it is part of.

1 Like

Thanks scruti for letting me know that. I thought giving the 2nd pattern match colon : (here) makes the sed to handle the input lines as : delimited.

It would mean if the line starts with Chocolate then if the line contains a colon : then substitute.....