Как заменить / отфильтровать "$ \ n (заключить в конец строки новую строку), используя grep, awk и sed в bash? - PullRequest
0 голосов
/ 05 марта 2019

У меня есть проект Java, который имеет много строк, которые выглядят следующим образом:

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

Мне нужно выполнить поиск bash для этого:

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

Я пробовал такие вещи, как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

Однако ни один из них не дает мне того, что я хочу, - все уникальные строки, передаваемые в метод myMethod.

Итак, как мне поступить?заменить или отфильтровать "$\n (заключить в конец строки новую строку), используя grep, awk и sed в bash?

Ответы [ 6 ]

2 голосов
/ 05 марта 2019

Попробуйте это (GNU grep и GNU sed, я полагаю, вы используете их):

$ 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";

Я полагаю, что это будет работать для нескольких файлов и нескольких экземпляров.
Я использовал sed читать после строк до тех пор, пока он не найдет закрытое значение ), а затем объединить.

1 голос
/ 05 марта 2019

Это то, что вы пытаетесь сделать (используя GNU sed для -z и распознавание \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

Если строка, передаваемая в myMethod, может содержать экранированные " s, тогда вам просто нужно сообщить нам, как они экранированы (удвоено?

0 голосов
/ 06 марта 2019

Это будет проходить (локально в текущем каталоге) через все файлы, в которых есть строка myMethod, читая метод до включения сигнала ); и заменяя его одним вкладышем:

>>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");

Обратите внимание, что при тестировании вы должны убрать флаг -i с последнего sed.-i изменит / перезапишет ваши файлы мгновенно, и вы не захотите этого перед тестированием.

0 голосов
/ 05 марта 2019

Нет необходимости в других инструментах;это можно сделать только с помощью bash.

$ 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

Используется функция bash, называемая «подстановка шаблонов», которая является частью «Расширения параметров», о которой вы можете прочитать на справочной странице bash или на официальном bash документация .

0 голосов
/ 05 марта 2019

что-то, что работает именно на ваших предоставленных строках и форматировании (кавычки и символы "+" включены), будет выглядеть так:

>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 извлекает все между строкой [myMethod] и первым появлением строки [");]

затем у нас есть другое значение sed, и первое выражение удаляет все символы новой строки, второе выражение удаляет двойные кавычки, 3-е выражение удаляет символы "+" и, наконец, последнее выражение удаляет строку "myMethod" из окончательного вывода

если вы хотите сделать это абсурдно, вы можете добавить [-e "s / [()] / \" / g "], чтобы преобразовать начальные и конечные скобки () вывода в двойные кавычки"

L.E: это, очевидно, испортит ваш код, если в вашем коде есть какие-либо из следующих символов: [+ "() myMethod]

0 голосов
/ 05 марта 2019

попробуйте, если это работает для вас:

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

Для вашего ввода это даст "некоторый текст здесь ... ... больше текста здесь ... и еще больше текста здесь".при необходимости вы можете легко исправить начальный пробел.

В основном используйте шаблон диапазона: ищите только между строкой myMethod( и концом вызова функции );, а затем захватывайте и объединяйте $2.Это не будет работать, если несколько аргументов функции в одной строке, хотя.вам также может понадобиться рассмотреть пробелы до myMethod( и после );.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...