LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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 10-11-2007, 06:30 AM   #1
fuzzyBuzz
Member
 
Registered: Sep 2005
Posts: 34

Rep: Reputation: 15
Search-replace in code


Hi,

I have code that currently uses the function:
void getMyTime(MyTimeStruct*);
and i would like to replace all calls to this function to calls to a different function with a prototype:
MyTimeStruct newGetMyTime(void);

For example, i would like the following line:
getMyTime(&startTime);
to be changed to:
startTime = newGetMyTime();

Is there any easy automated way to do this?
 
Old 10-11-2007, 06:39 AM   #2
Centinul
Member
 
Registered: Jun 2005
Distribution: Gentoo
Posts: 552

Rep: Reputation: 30
You could try using something like SED on each of your files that has that function in it. Your request seems simple enough that beginner SED tutorials on Google should get you where you need to be. If I remembered the syntax I would write it out.

HTH,

Centinul
 
Old 10-11-2007, 06:39 AM   #3
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
You can do this in one statement using some combination of cat, grep & sed, with sed being the main ingredient (and sed probably can do it all by itself, without grep or cat).

Check out the man page for sed.
 
Old 10-11-2007, 08:12 AM   #4
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
If you're doing a large global replace in a lot of files, be careful - what if the string you are replacing is a sub-string of another function name which you do not want to modify? Check first.

Perl has some nice regular expression extensions which can help, e.g. the \b pattern (word boundary), and you can user Perl on the command like much like sed and friends., e.g.
Code:
perl -i.original -npe 's/\bmain\b/MAIN/g' *.c
...will replace all instances of the whole word "main" with "MAIN" in all files whose name ends in ".c", saving the original version of the file with the name suffix ".original" (e.g. test.c becomes test.c.original).
 
Old 10-11-2007, 08:24 AM   #5
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Oh, for removing the stuff between the brackets, you need to add a little something. Don't forget to escape the brackets with a \ character since they are special characters in regular expressions, i.e. the Perl code is like this:
Code:
perl -i.original -npe 's/\bgetMyTime\s*\([^)]*\)/newGetMyTime()/g;' *.c
You can look in the perlrun manual page to see what the -i, -n, -p, and -e options do. The Perl program (the bit in the single quotes) consists of a single substitution operation. The syntax is
Code:
s/replacethis/withthis/flags;
Where:
  • replacethis is a Perl-style regular expression pattern to search for (see perlre manual page),
  • withthis is what to replace found-patterns with.
  • flags is a list of single character options which modify the behaviour of operation. "g" means global - replace all instances of the pattern on a given input line instead of just the first match, which is the default behaviour.
A more detailed description of the substitution operator can be found in the perlop manual page.
 
Old 10-11-2007, 10:56 PM   #6
angrybanana
Member
 
Registered: Oct 2003
Distribution: Archlinux
Posts: 147

Rep: Reputation: 21
This command should work
Code:
$ cat a
getMyTime(&startTime);

$ sed 's/\(.*\)(&\(.*\))/\2 = new\1()/' a
startTime = newgetMyTime();
 
Old 10-12-2007, 02:14 AM   #7
fuzzyBuzz
Member
 
Registered: Sep 2005
Posts: 34

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by angrybanana View Post
This command should work
Code:
$ cat a
getMyTime(&startTime);

$ sed 's/\(.*\)(&\(.*\))/\2 = new\1()/' a
startTime = newgetMyTime();
This exactly what i had in mind. Thanks.
 
Old 10-12-2007, 02:56 AM   #8
fuzzyBuzz
Member
 
Registered: Sep 2005
Posts: 34

Original Poster
Rep: Reputation: 15
Based on angrybanana's sed command i created a substitution that only affects getMyTime function.
Code:
$ cat a
getMyTime(&startTime);
setMyTime(&startTime);
$ cat s
s/getMyTime(&\(.*\))/\1 = newGetMyTime()/
$ sed -f s a
startTime = newGetMyTime();
setMyTime(&startTime);
I had to put the command in a script file because i am running under cygwin and the ampersand character (&) in the regular expression is confusing the shell. Any way to use ampersand in regular expressions in the shell?
 
Old 10-12-2007, 08:09 AM   #9
angrybanana
Member
 
Registered: Oct 2003
Distribution: Archlinux
Posts: 147

Rep: Reputation: 21
Quote:
Originally Posted by zvirack View Post
I had to put the command in a script file because i am running under cygwin and the ampersand character (&) in the regular expression is confusing the shell. Any way to use ampersand in regular expressions in the shell?
Dunno much about cygwin, but you could try double quotes (") or backslash (\).
 
Old 10-13-2007, 05:02 PM   #10
fuzzyBuzz
Member
 
Registered: Sep 2005
Posts: 34

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by angrybanana View Post
Dunno much about cygwin, but you could try double quotes (") or backslash (\).
Tried that but didn't work for me.
 
Old 10-14-2007, 01:15 PM   #11
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
Use backslash and double quotes, or single quotes:

Code:
$ cat a.c
getMyTime(&startTime);
setMyTime(&startTime);

$ sed 's/getMyTime(&\(.*\))/\1 = newGetMyTime()/' a.c
startTime = newGetMyTime();
setMyTime(&startTime);

$ sed "s/getMyTime(\&\\(.*\\))/\\1 = newGetMyTime()/" a.c
startTime = newGetMyTime();
setMyTime(&startTime);
 
Old 10-15-2007, 01:12 AM   #12
fuzzyBuzz
Member
 
Registered: Sep 2005
Posts: 34

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ntubski View Post
Use backslash and double quotes, or single quotes:

Code:
$ cat a.c
getMyTime(&startTime);
setMyTime(&startTime);

$ sed 's/getMyTime(&\(.*\))/\1 = newGetMyTime()/' a.c
startTime = newGetMyTime();
setMyTime(&startTime);
This form doesn't work in cygwin. I get the following error message:
Code:
sed: -e expression #1, char 12: unterminated `s' command
'\' is not recognized as an internal or external command,
operable program or batch file.
Quote:
Originally Posted by ntubski View Post
Code:
$ sed "s/getMyTime(\&\\(.*\\))/\\1 = newGetMyTime()/" a.c
startTime = newGetMyTime();
setMyTime(&startTime);
This form works in cygwin! Thanks for the tip.

I was wondering if there could be a more general regular expression that would substitute for all possible c forms of the statement. For example, include also the following cases:
  1. getMyTime (&startTime); // Spaces between function name and parenthesis
  2. getMyTime(
    &startTime
    )
    ; // Statement broken into several lines. This is a legal c statement.
 
Old 10-15-2007, 10:37 AM   #13
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
Quote:
Originally Posted by zvirack
This form doesn't work in cygwin. I get the following error message:
Maybe you miscopied the command? I actually tested both commands in cygwin before posting.

Quote:
Originally Posted by zvirack
I was wondering if there could be a more general regular expression that would substitute for all possible c forms of the statement. For example, include also the following cases:

1. getMyTime (&startTime); // Spaces between function name and parenthesis
2. getMyTime(
&startTime
)
; // Statement broken into several lines. This is a legal c statement.
sed is a line based tool, it might be possible to do this with pattern spaces or something but I'm not sure. Just spaces is easy though:

Code:
$ sed 's/getMyTime[ ]*([ ]*&[ ]*\(.*\)[ ]*)/\1 = newGetMyTime()/' a.c
startTime = newGetMyTime(); // Spaces between function name and parenthesis
getMyTime(
&startTime
)
; // Statement broken into several lines. This is a legal c statement. Not changed by the sed regexp though :(
 
  


Reply

Tags
perl, replace, search, sed


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
Batch search-and-replace? jkh107 Linux - Software 13 09-02-2007 10:03 AM
Advanced Search and Replace patrokov Linux - Software 33 07-09-2006 10:44 PM
Batch search and replace devilkin Linux - Newbie 2 02-14-2005 02:39 AM
search and replace C code vexer Programming 3 05-18-2004 11:11 PM
problem in perl replace command with slash (/) in search/replace string ramesh_ps1 Red Hat 4 09-10-2003 01:04 AM

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

All times are GMT -5. The time now is 07:29 PM.

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