简体   繁体   中英

How do I replace/filter out "$\n (quote end-of-line newline) using grep, awk, and sed in bash?

I have a Java project that has many lines that look like this:

myMethod("some text here ..."
+ " ... more text here"
+ " ... and even more text here");

I need to perform a bash search for this:

"some text here ... ... more text here ... and even more text here";

I have tried things like this:

# Filtering for text between the two parenthesis
$ grep -rn "myMethod" . | awk -F\( '{print $2}' | awk -F\) '{print $1}' | sort | uniq

# replacing the `"$\n` with nothing
$ grep -rn "myMethod" . | sed -e 's/"$\n\s//g' | sort | uniq

# same
$ grep -rn "myMethod" . | sed -e ':a;N;$!ba;s/"$\n/,/g' | sort | uniq

However, none of these is giving me what I want, which is all of the unique Strings being passed into the myMethod method.

So, how can I go about replacing or filtering out "$\\n (quote end-of-line newline) using grep, awk, and sed in bash?

Try this ( GNU grep and GNU sed , I believe you are using them):

$ cat file
myMethod("some text here ..."
+ " ... more text here"
+ " ... and even more text here");

$ grep -rzn "myMethod" . | sed -rn '/myMethod/{:a;s/\)//;tb;N;ba;:b;s/\n//g;s/[^"]*$//;:c;s/^[^"]*"([^"]*)"(.*)/\2\1/;tc;p;}'
some text here ... ... more text here ... and even more text here

$ grep -rzn "myMethod" . | sed -rn '/myMethod/{:a;s/\)//;tb;N;ba;:b;s/\n//g;s/[^"]*$//;:c;s/^[^"]*"([^"]*)"(.*)/\2\1/;tc;s/^/"/;s/$/";/;p}'
"some text here ... ... more text here ... and even more text here";

I believe it will work on multiple files and multiple occurrences.
I used sed to read after lines until it finds close paren ) and then concatenate.

Is this what you're trying to do (using GNU sed for -z and recognition of \\n )?

$ sed -z 's/"\n+ "//g' file
myMethod("some text here ... ... more text here ... and even more text here");

$ sed -z 's/"\n+ "//g' file | sed -n 's/^myMethod("\([^"]*\).*/\1/p'
some text here ... ... more text here ... and even more text here

If the string being passed to myMethod can contain escaped " s then you'd just need to tell us how they're escaped (doubled? backslashed? something else?) and then they'd be easy to handle.

try if this works for you:

awk -F'"' '/^myMethod\(/,/\);$/{str = str " " $2}END{print str}' file

For your input, this will yield " some text here ... ... more text here ... and even more text here". you can fix the leading space easily if needed.

Basically use the range pattern: search only between string myMethod( and the end of function call ); and then grab and concatenate $2 . This will not work if multiple function arguments on the same line though. you might also need to consider the white spaces before myMethod( and after ); .

something that works exactly on your provided strings and formatting (quotes and "+" symbols included) would look like this:

>cat my_file.txt
myMethod("some text here ..."
+ " ... more text here ..."
+ " ... and even more text here");
other lines
and some other");

>sed -n '/myMethod/,/");/p' my_file.txt | sed -e ':a;N;$!ba;s/\n/ /g' -e "s/\"//g" -e "s/\+//g" -e "s/myMethod//g"
(some text here ...   ... more text here ...   ... and even more text here);

first sed extracts everything between string [myMethod] and first occurrence of string [");]

then we have another sed and first expression eliminates all newlines character, second expression eliminates the double quotes, 3rd expression eliminates the "+" symbols and finally the last expression removes the "myMethod" string from final output

if you want this absurdly done, you can add [-e "s/[()]/\\"/g"] to transform the leading and ending parentheses () of output, into double quotes "

LE: this will obviously mess up with your code if you have any of the following characters inside you code: [+"()myMethod]

No need for other tools; this can be done with bash alone.

$ s=$'myMethod("some text here ..."\n+ " ... more text here"\n+ " ... and even more text here");'
$ echo "$s"
myMethod("some text here ..."
+ " ... more text here"
+ " ... and even more text here");
$ t="${s//$'\n'/ }"
$ t="${t//\" + \"/ }"
$ t="${t#myMethod(\"}"
$ t="${t%\");}"
$ echo "$t"
some text here ...  ... more text here  ... and even more text here

This uses a bash feature called "pattern substitution" which is part of "Parameter Expansion" which you can read about on bash's man page or the official bash documentation .

This will go (locally in current dir) through all the files that have string myMethod in them, reading the method until enclosing signal ); and replacing it with a one liner:

>>cat my_file.txt
random first line
random second line

myMethod(first line of code
second line of code
third line of code);
# notice above method ending in string ");". This is important to mark the enclosing of the method.
# this string should not be present anywhere else withing the content of the method

other lines
and some other");
>>cat other_file.txt
myMethod("text in other file ..."
+ " ... yet more text from other file ..."
+ " ... and even more text here from the second file"); # ending of method
other lines
and some other");
ACTUAL COMAND
>>for file_containing_myMethod in `grep -l "myMethod" *`; do ONE_LINER=`sed -n '/myMethod/,/);/p' ${file_containing_myMethod} | sed -e ':a;N;$!ba;s/\n/ /g'`; sed -i "/myMethod/,/);/{/);/ s/.*/${ONE_LINER}/; t; d}" ${file_containing_myMethod}; done
random first line
random second line

myMethod(first line of code second line of code third line of code);
# notice above method ending in string ");". This is important to mark the enclosing of the method.
# this string should not be present anywhere else within the content of the method

other lines
and some other");

myMethod("text in other file ..." + " ... yet more text from other file ..." + " ... and even more text here from the second file"); # ending of method
other lines
and some other");

Please note that when you test you should eliminate the -i flag from the last sed . -i will change/rewrite your files instantly, and you don't want that before testing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM