[SOLVED] Need sed help: s/ command won't replace two occurrences of pattern on same line
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
sed 's~\(\$(.*\\\$\){\$\([0-9a-zA-Z]*\)\([[]\)\([0-9a-zA-Z]*\)\([]]\)})~\1\${\2}_\4)~g'
Which works great when there's only ONE of the pattern on the line. But in a case like the "actual line" I posted first, where there are two patterns, separated by a slash, only ONE gets replaced
Why?? There must be (among many other things) something I'm not knowing about sed, that's causing this.
NOTES:
-- I'm currently using the ~ (tilde) as the separator in the sed command. It doesn't matter, I've used / ~ and % with no difference.
-- As a test, I tried putting a different character(s) in the middle of the original pattern instead of the / but that made no difference.
-- I've come up with various similar but slightly different regexs that will do this replacement, but they all have had this same result.
-- I tried the sed single-quoted, double-quoted, and unquoted; the latter fails to execute, and the formers both work as described here: wrong.
OK, it just occurred to me that as a work-around, I can execute the sed -i against the file I'm editing, and then execute the sed AGAIN against the edited file, and with two passes at it like that, the line(s) in question will get sedded. But this doesn't address why it doesn't work in one pass.
WTF now it's working... This is ridiculous. I put some more of the actual line, into the pattern to match (which I've done loads of times by now) and this time, it works:
First, I assumed that the non-fixed portions were just "i2" (regex = [a-z][0-9]) and "2" (regex= [0-9]) These are the only pieces that I put into backreferences.
Egads! So much simpler to do it that way -- a whole lot less freaking s*** in the regex, that's for sure :/ though this is a big script I'm batch-editing with sed, and there are a lot of slightly different incarnations of these crazy eval/echo/array things, so maybe I'm on the safe side to include the more details in the regexes -- either way, thanks for that simpler suggestion.
The problem with your original pattern was using ".*": sed regex's are greedy so
Code:
sed 's~\(\$(.*\\\$\){\$\([0-9a-zA-Z]*\)\([[]\)\([0-9a-zA-Z]*\)\([]]\)})~\1\${\2}_\4)~g'
matches
blah blah blah=$(eval echo \${$i2[2]})/$(eval echo \${$i2[3]})
rather than
blah blah blah=$(eval echo \${$i2[2]})/$(eval echo \${$i2[3]})
as you intended
you are doing this for one time only , right?
Not that it matters, but i would still recommend not doing this in shell but a programming language. it will benefit you in future.
Last edited by ghostdog74; 12-15-2009 at 11:53 PM.
Doing 'what' exactly for one time only? This sed thing? Well, more than one time, yes, but all for one occasion, that being the process of converting this 2300+ line shell program over from using arrays, to NOT using arrays, so it can become portable. I'm using this concept we discussed over there: http://www.linuxquestions.org/questi...rings.-775622/ to replace the arrays.
And I am tickled to report that as of 20 minutes ago, IT IS WORKING!!! I'm done! The whole script has been converted, thanks in large part to a sequence of sed's more-or-less like the situation above, and some finishing touches with search+replace in my text editor. The script now runs in Dash too!!
As for "other languages", as much as I'd really love to be an excellent C programmer (for the sake of argument, but it could be <whatever> language), AND while there may/probably/likely be languages better suited to do some things that I do, I actually really enjoy the challenge of creating stuff in shell and besides, the amount of time I would spend becoming competent enough in another language to do something useful, could be better spent IMHO getting better in shell. Like they sometimes say, "Go with what you know.".
My ability in C for example is enough that I can debug most problems I encounter with pre-existing code, and I've sent a couple very tiny patches to the linux kernel, but I don't pretend for a second that I can write my own program from scratch in C. I put a tiny bit of time into it, and have lots of reading material, but I don't spend enough time to expect to become competent with it.
Sasha!!
Last edited by GrapefruiTgirl; 12-16-2009 at 02:09 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.