LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-16-2009, 09:58 AM   #1
carolflb
Member
 
Registered: Oct 2009
Posts: 40

Rep: Reputation: 15
BASH: how to substitute a expression with another without creating a new file


Hi guys,

I'm writting a script in BASH and I want to find the expression "int foo[i] = true;" in a text and substitute it by the word "boo[i]= true;", but without erasing other words from the text and without having to create a new file. Would somebody know how I can do that?

Text for example:

whi(&M)/&M)POM;M;(29073()/()"/;();/()"7ZE/)&=)"&/=)$&=!&$=!
waxe83qmi3u,jy,einure,xl9me23uy9, int foo[i] = true;i23904802y97p,94280
u2908/M="(?;$(/EZ"Zolsdwiea,ru8
q2xi4l9i<ey93
2x5093405
int foo[i]= true;
39i2e09ui9,y92i049.
 
Old 11-16-2009, 10:19 AM   #2
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974
sed -i -e 's/int\ foo\[i\]=true\;/something\ else/g' myfile

TBH, the escape characters mightn't be exactly correct, but it's the -i option for sed you're really looking for.
 
Old 11-16-2009, 10:30 AM   #3
carolflb
Member
 
Registered: Oct 2009
Posts: 40

Original Poster
Rep: Reputation: 15
Hi Cris!

That works perfectly. Thanks a lot

Actually would you also know how can I tell 'sed' to substitute just the first match?

Last edited by carolflb; 11-16-2009 at 10:33 AM.
 
Old 11-16-2009, 12:03 PM   #4
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417

Rep: Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974Reputation: 1974
well the "g" makes sed do multiple replacements in the same line, so if you remove that it'll only do it once per line.
 
Old 11-16-2009, 10:35 PM   #5
stevenworr
LQ Newbie
 
Registered: Oct 2008
Posts: 13

Rep: Reputation: 1
Why execute sed as an external process when bash can just do it inline?

Code:
#! /bin/bash

match='int foo\[i\] = true;'
while read line
do
    [[ "$line"  =~ "$match" ]] && line="${line/$match/something else}"
    echo "$line"
done
Quote:
${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in pathname
expansion. Parameter is expanded and the longest match of pat-
tern against its value is replaced with string. If Ipattern
begins with /, all matches of pattern are replaced with string.
Normally only the first match is replaced. If pattern begins
with #, it must match at the beginning of the expanded value of
parameter. If pattern begins with %, it must match at the end
of the expanded value of parameter. If string is null, matches
of pattern are deleted and the / following pattern may be omit-
ted. If parameter is @ or *, the substitution operation is
applied to each positional parameter in turn, and the expansion
is the resultant list. If parameter is an array variable sub-
scripted with @ or *, the substitution operation is applied to
each member of the array in turn, and the expansion is the
resultant list.
 
Old 11-16-2009, 10:55 PM   #6
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Code:
$  more file
whi(&M)/&M)POM;M;(29073()/()"/;();/()"7ZE/)&=)"&/=)$&=!&$=!
waxe83qmi3u,jy,einure,xl9me23uy9, int foo[i] = true;i23904802y97p,94280
u2908/M="(?;$(/EZ"Zolsdwiea,ru8
q2xi4l9i<ey93
2x5093405
int foo[i]= true;
39i2e09ui9,y92i049.
int   foo[i]    =     true
the end

$ awk '{gsub(/int[ ]+foo\[i\][ ]*=[ ]*true/,"---")}1' file

whi(&M)/&M)POM;M;(29073()/()"/;();/()"7ZE/)&=)"&/=)$&=!&$=!
waxe83qmi3u,jy,einure,xl9me23uy9, ---;i23904802y97p,94280
u2908/M="(?;$(/EZ"Zolsdwiea,ru8
q2xi4l9i<ey93
2x5093405
---;
39i2e09ui9,y92i049.
---
the end
 
Old 11-16-2009, 10:58 PM   #7
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by stevenworr View Post
Why execute sed as an external process when bash can just do it inline?

Code:
#! /bin/bash

match='int foo\[i\] = true;'
while read line
do
    [[ "$line"  =~ "$match" ]] && line="${line/$match/something else}"
    echo "$line"
done
these will not match:
Code:
1) int foo[i]= true
2) int    foo[i]   =  true
3) int foo[i] =true
 
Old 11-17-2009, 01:09 AM   #8
stevenworr
LQ Newbie
 
Registered: Oct 2008
Posts: 13

Rep: Reputation: 1
Quote:
Originally Posted by ghostdog74 View Post
these will not match:
Code:
1) int foo[i]= true
2) int    foo[i]   =  true
3) int foo[i] =true
You have to give bash what it wants to do the job. You can make this as hard as you want or only as hard as you need.
Code:
match=$'int[ \t]+foo\[i\][ \t]*=[ \t]*true[ \t]*;'
Then you can do stuff like

Code:
[[ "$line" =~ "$match" ]] && line="int boo[i] = true;
Feel free to add as many extra paren groupies to exactly preserve as much whitespace as you need.

If you really want to go ape

Code:
match=$'int([ \t]+)foo\[i\]([ \t]*=[ \t]*)true([ \t]*);'
[[ "$line" =~ "$match" ]] && line="int${BASH_REMATCH[1]}boo[i]${BASH_REMATCH[2]}true${BASH_REMATCH[3]};"
Note that I am using $'stuff' to embed a tab in a string and I use the BASH_REMATCH array to access the parts of the match that I care to reproduce. It's all in the bash man page.
 
Old 11-18-2009, 09:42 AM   #9
carolflb
Member
 
Registered: Oct 2009
Posts: 40

Original Poster
Rep: Reputation: 15
Hi guys,

first thanks for all replies

I think I didn't express myself the right way. What I wanted to ask with "would you also know how can I tell 'sed' to substitute just the first match?" was that I want to know if it's possible to use 'sed' to erase or substitute just the first occurency of the searched pattern in the file, so if I have:

text
text PATTERN
text
PATTERN
text
PATTERN
text


So, is there a way of substituting the first occurency of PATTERN in the file and erasing the other ones? So that at the end I have:


text
text SUBSTITUTED PATTERN
text
text
text
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
[SOLVED] BASH - how to substitute many lines in a text file at once carolflb Linux - Newbie 6 10-20-2009 01:28 PM
[SOLVED] BASH - how to substitute many lines in a text file at once carolflb Programming 2 10-20-2009 10:21 AM
[SOLVED] [bash] rm regular expression help RaptorX Programming 26 08-01-2009 06:29 PM
bash shell script expression CowboyJ Programming 2 04-24-2005 11:33 PM


All times are GMT -5. The time now is 03: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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration