Link to home
Start Free TrialLog in
Avatar of lcor

asked on

SED Command to Insert Logging Line in Java File

I need to modify alot of java files so that each method prints a logging message so hopefully sed will do the trick for me.

Here's an example of the file change.
public void someMethod(int x) {
     System.out.println("xx"); // Sed command should add this line to the java file for every method in the file

Open in new window

I tried using the following sed command to look for public as the starting pattern and the ending pattern of right paren, space, left bracket.
sed '/public/,/) {/a System.out.println("xx);'

Open in new window

but this doesn't work.  It prints the logging statement mutliple times after below the public method call.

Any ideas what could be wrong?
Avatar of noci

you say: from  a line containing public , until a line with } {, append some data...,
The next should work better.(\ is needed to keep the spaces, otherwise spaces get ignored).

sed -i~ '/^public .*) {$/a \ \ \ \ \ \ \ System.out.println("xx");' 

Open in new window

Which matches a line starting with public and ending with ) {....  with all on one line.
Flag of India image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
sed -iwhataever   ......

Will make a backup anywait with whatever appended.., customary:   sed -i~
Hi murugesandins,

I have some questions about the things you've added to noci's solution.  Let's take your last solution as an example, i.e.:
    /bin/sed -i 's/\(.*public.*(.*{\)/\1\n     System.out.println("xx")\;/;'  ./

You said at the top, "Better use full path", but you haven't explained why.
Q1. Please explain why you think it's better to use the full path.
Q2. What is the benefit of using "./" instead of just "" in this context?

Example on using full path exception:
rm -rf / home/oracle/delete.txt >/dev/null 2>/dev/null &
Remember the space between / and home/oracle/delete.txt
Mentioned ./ to use related path.
Either ./ /one/two/tjree/
If user using better use
export PS1='$LOGNAME@$HOSTNAME $PWD [ $? ]
$ '
Either $HOSTNAME or $IP (obtained using /sbin/ip -f inet addr show dev eth0 => eth0 or ...)
to display $PWD always so that we know what which being modified.

>> Proceed based on command given by noci.
I have not forced to accept my comment.
Hi murugesandins,

I don't see how your answers answer my questions.  You seem to be either misunderstanding my English, or not responding in clear English.

The full path I referred to was this:
    /bin/sed ...
Q1a. Please explain why you think it's better to use "/bin/sed ..." instead of "sed ..." in this context.

Q2a. Please answer again, simply and clearly.  How is this:
    /bin/sed -i 's/\(.*public.*(.*{\)/\1\n     System.out.println("xx")\;/;'  ./
better than this?:
    /bin/sed -i 's/\(.*public.*(.*{\)/\1\n     System.out.println("xx")\;/;'

Q2b. What has "/sbin/ip..." got to do with this?

$ unalias sed >/dev/null 2>&1
$ unset -f sed >/dev/null 2>&1
$ alias sed='echo Better use full path using /bin/sed'
$ sed -i ./
Better use full path using /bin/sed -i ./

Open in new window

Leave my comment given on IP (not related to current query).

Assume that
1) $PWD not present in PS1='$'
2) We are in different directory having /bin/sed will be modifying at different directory (exception may happen) to modify different file.
a. use related path before modification.
b. use PS1 to have $PWD
c. Use related path. I have mentioned ./ => means use related path => before modification.
For Q2b (not related to 29140984 query)
I have mentioned only my PS1 usage.
export PS1='$LOGNAME@$IP $HOSTNAME $PWD [ $? ]
$ '
to display current IP address /usr/bin/hostname
To obtain current IP address mentioned the command /sbin/ip (at all Linux oriented platforms) and /cygdrive/c/windows/system32/ipconfig.exe at Windows Cygwin.
What do you think PS1 does?  You know it's just the prompt, so what it contains doesn't affect the result of any commands, right?
I agree.
>> For Q2b (not related to 29140984 query)
Due to my health issue, PS1 helps me a lot on:
a. concentration
b. all exceptions.
Regarding Q1:
Full path / short path...    always be sure that you type what you mean to type.
typo's can be made anywhere and any typo will have unexpected consequences.

Regarding Q2: ./  and are FULL equivalent...  the OS Opens these as:
$PWD/./     or $PWD/
(ie. $PWD is prepended when opening a file... (Well tbh. The kernel has an open inode internal for the $PWD and uses that, $PWD is only used by the shell).
This can be observed by using lsof and look for a "cwd" entry.

So "better" in this aspect  is what a person appreciates the most....  When potentially destroy data verify before destory is allways a wise move.

Full path in commands might be needed for cronjobs / atd jobs.  Those have different PATH settings from "regular" shell jobs.
So when scripts might execute there a ful path might be needed. It may also bite you ...
Some distro's place scripts in /bin, others in /usr/bin ... (/sbin res. /usr/sbin) ... when referring to the wrong place it won't work ....
So for scripts that are used locally and those can be hardcoded, for scripts meant for multiple environments maybe a whereis or explicit check is needed.

For command line use (i expected the oneliner to be used for) no scripting around it is needed, no explicit paths for the command are needed.
and -isomething does make backup copies... transferring all responsibility back to the sed command....
Thanks for your response, noci.

It looks as if you are trying to answer my Q1 & Q2 from here, right?  I was really trying to get murugesandins to answer, because I think he should be able to explain why he is proposing that kind of coding, but I'm finding his responses confusing and made worse with irrelevancies about things like $PS1, so let's look at your answers.

I was aware of the issue with $PATH being potentially different for cron, but in my sysadmin experience I've never found that commands like sed were not found in $PATH for cron, or any other account.
The other reason I've heard relates to security, e.g. if someone writes some malicious code and and somehow puts it in a file called "sed", then puts that somewhere near the beginning of the $PATH of a user or cron or whatever.  Pretty unlikely to happen, I expect, especially if security is set up appropriately.  If, for example, a hacker managed to get root access they could replace /bin/sed itself anyway, but I guess some hackers get access to some other account (not root), so they can't replace files like /bin/sed.

"Full path / short path...    always be sure that you type what you mean to type.
typo's can be made anywhere and any typo will have unexpected consequences."

Q3. What has this got to do with my question Q1?  This one-liner is what I was talking about:
         /bin/sed -i 's/\(.*public.*(.*{\)/\1\n     System.out.println("xx")\;/;'  ./

...When potentially destroy data verify before destory is allways a wise move.
Q4. Has this verification suggestion got anything to do with my Q2, which is about using references like ./ instead of just for files which are in the current working directory?

Thanks for the info on $PWD which I was unaware of.