2

I keep reading the sed documentation and lots of posts but can't seem to figure this out. I have a large number of Java files. In those files are calls to a method that take the enumeration converted to an integer using the toInt() method. I want to go through all of the files and get rid of .toInt() for a specific enumeration.

This is what I want. The original code strings:

foo(ENUM_NAME.ENUM_VALUE.toInt(), arg2, arg3)
foo(ENUM_NAME.ENUM_VALUE2.toInt(), arg2, arg3)

I want to end up with:

foo(ENUM_NAME.ENUM_VALUE, arg2, arg3)
foo(ENUM_NAME.ENUM_VALUE2, arg2, arg3)

ENUM_VALUE could be hundreds of different possibilities so I can't hard code. It appears there is some confusion as to what needs to change so I will try to be more clear.

There is an enumeration called TRANF_FIELD in my Java files. The values available for that enumeration could be one of a two thousand values, followed by .toInt(). I need to get rid of the .toInt(). The function names are all irrelevant.

The following are examples of code constructs that are interspersed throughout my Java code and how they should be processed:

TRANF_FIELD.TRANF_VALUE_1.toInt()
                I want the .toInt() deleted, leaving TRANF_FIELD.TRANF_VALUE_1 left over.
TRANF_FIELD.TRANF_KILL_ME.toInt()
                I want the .toInt() deleted, leaving TRANF_FIELD.TRANF_KILL_ME
TRANG_FIELD.TRANG_VALUE_1.toInt()
                No change, because it's not TRANF_FIELD.
TRANF_FIELD.TRANF_VALUE_1.length()
                No change, because it's not .toInt().

  • Will the format always be string(string.string.string(), string, string) and you will always want to get rid just of the string()? Can it be string(string.string(), string) for example? – confused00 Oct 7 '14 at 15:13
  • It could be a lot of different things but I know it is not realistic to get everything covered. If I could get something like ENUM_NAME.ENUM_VALUE.toInt() replaced with ENUM_NAME.ENUM_VALUE it would be a good start. – Chris Oct 7 '14 at 15:17
  • that's just something like awk -vFS='[.)]' '{print $1"."$2$4")"}' – confused00 Oct 7 '14 at 15:20
  • That works if I only have the enumerations in a file. The problem is that the lines are mixed in with other code so it falls apart. – Chris Oct 7 '14 at 15:31
  • I'd need to know how the input looks to know what not to match – confused00 Oct 7 '14 at 15:34
1

You seem to want to change all occurrences of

TRANF_FIELD.some_enum_value.toInt()

to

TRANF_FIELD.that_enum_value

while leaving other enumerations (e.g., TRANG_FIELD.TRANG_VALUE.toInt()) and other methods (e.g., TRANF_FIELD.TRANF_VALUE.length()) alone.  This seems simple:

sed 's/\(TRANF_FIELD\.[A-Za-z0-9_]*\)\.toInt()/\1/'

where

  • [A-Za-z0-9_]* is any number of alphanumeric characters (including underscores).  This is intended to match any valid enumeration value.  Actually, [A-Za-z_][A-Za-z0-9_]* would be better, because [A-Za-z0-9_]* could match an empty string, or one beginning with a digit.
  • \(\) groups the enumeration name (TRANF_FIELD), the literal period (\.), and the enumeration value (from the first bullet).
  • \1 means “replace the complete string that you found with the first group”, i.e., discard the .toInt() part.
  • To handle multiple occurrences per line, add g (global) after the last slash.
  • This will not handle embedded whitespace, e.g., TRANF_FIELD . TRANF_VALUE.  Fixing this is left as an exercise.
  • This will not handle expressions that are broken across lines; e.g.,

        i = TRANF_FIELD
                 .TRANF_VALUE.toInt();
    

    That’s harder to fix.

  • That is what I needed G-Man. I couldn't figure out how to get it to to keep the TRANF_VALUE part. I knew it had something to do with the \1 but I couldn't get it to work. I can handle split lines manually. I just didn't want to hand modify hundreds of files. – Chris Oct 7 '14 at 17:27
1

Thanks for all of your help folks. I added the -i from one answer, including the path to all java files, to what G-man suggested and it works. If you guys are ever on Long Island i'll buy you a beer. That saved me a bunch of time.

sed -i 's/\(TRANF_FIELD\.[A-Za-z0-9_]*\)\.toInt()/\1/g' 
  • @Mohsen: Seriously? You rejected my edit because I fixed problems with punctuation and capitalization? – G-Man Oct 7 '14 at 18:09
  • Oh, sorry, i made a mistake, i think you edit post, sorry. – PersianGulf Oct 7 '14 at 18:49
0

Depending on your OS, an inline (-i) sed could do this:

sed -i 's:\.toInt()::' filename

Where it will just substitute the instance of ".toInt()" with "" - the . is escaped so that it does not act as a wild card.

As you mention multiple files, then you will have to loop this command by searching for all files in the current directory and sub directories:

find . -type f -exec sed -i 's:\.toInt()::' {} \;

However, this will error if filenames contain spaces, so we can use the xargs command to deal with this which will place quotes around all filenames:

find . -type f | xargs -I{} sed -i 's:\.toInt()::' "{}"

However, this will also pick compiled files too so to avoid these we can use a useful feature in perl to ignore them:

find . -type f | perl -nle 'print if -T' | xargs -I{} sed -i 's:\.toInt()::' "{}"

-1
sed 's/ENUM_NAME\.\(.*\)\.toInt()/ENUM_NAME.\1/g' 
  • 2
    Please expand this answer. One line answers are discouraged, since they often include complex actions that others, including the OP, may not fully understand. – slm Oct 7 '14 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.