LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-15-2009, 10:33 PM   #1
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Angry Need sed help: s/ command won't replace two occurrences of pattern on same line


Here's the actual line of code, which exists in a bash script:

Code:
blah blah blah=$(eval echo \${$i2[2]})/$(eval echo \${$i2[3]})
I want to replace instances like this:
Code:
$(eval echo \${$i2[2]})
with this:
Code:
$(eval echo \$${i2}_3)
Using this:
Code:
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

Watch:
Code:
shell# echo '$(eval echo \${$i2[2]})' | sed 's~\(\$(.*\\\$\){\$\([0-9a-zA-Z]*\)\([[]\)\([0-9a-zA-Z]*\)\([]]\)})~\1\${\2}_\4)~g'
$(eval echo \$${i2}_2) <--replaced!

shell# echo '$(eval echo \${$i2[2]})/$(eval echo \${$i2[3]})' | sed 's~\(\$(.*\\\$\){\$\([0-9a-zA-Z]*\)\([[]\)\([0-9a-zA-Z]*\)\([]]\)})~\1\${\2}_\4)~g'
$(eval echo \${$i2[2]})/$(eval echo \$${i2}_3)
    ^^^ not replaced ^^        ^^^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.

Please help!

Sasha
 
Old 12-15-2009, 10:41 PM   #2
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
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.
 
Old 12-15-2009, 10:44 PM   #3
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
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:

Quote:
echo '$(eval echo \${$i2[2]})/$(eval echo \${$i2[3]})' | sed 's~\(\$(eval echo \\\$\){\$\([0-9a-zA-Z]*\)\([[]\)\([0-9a-zA-Z]*\)\([]]\)})~\1\${\2}_\4)~g'

$(eval echo \$${i2}_2)/$(eval echo \$${i2}_3) <--both occurrences fixed.
Phooey.....

Last edited by GrapefruiTgirl; 12-15-2009 at 10:45 PM.
 
Old 12-15-2009, 11:04 PM   #4
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
I did it like this:

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.

I put the string into a file, and:
Code:
mherring@Ath ~]$ more sasha
$(eval echo \${$i2[2]})/$(eval echo \${$i2[3]})
[mherring@Ath ~]$ sed 's%\${\$\([a-z][0-9]\)\[\([0-9]\)\]}%\$\${\1}_\2%g' sasha
$(eval echo \$${i2}_2)/$(eval echo \$${i2}_3)
[mherring@Ath ~]$
 
1 members found this post helpful.
Old 12-15-2009, 11:07 PM   #5
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
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.

Thanks.
Sasha
 
Old 12-15-2009, 11:19 PM   #6
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
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
 
1 members found this post helpful.
Old 12-15-2009, 11:23 PM   #7
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
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.
 
Old 12-16-2009, 02:08 AM   #8
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Original Poster
Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556


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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to replace string pattern with multi-line text in bash script? brumela Linux - Newbie 6 04-21-2011 06:56 AM
Sed to read the file and replace and insert the pattern saurabhchokshi Programming 2 06-12-2009 01:15 PM
replace a pattern with a line using sed/awk lokeshn05 Linux - Newbie 3 05-06-2009 03:01 PM
sed display line after pattern match inonzi_prowler Linux - Software 3 02-19-2007 01:47 PM
replacement with sed: replace pattern with multiple lines Hcman Programming 5 11-18-2004 07:40 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:57 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration