메소드의 첫 번째 줄 로거에 Java 메소드 이름을 추가해야 하는 요구 사항이 있습니다.
다음 접근 방식을 시도하고 있습니다.
- 키워드 또는 및 문자가 포함된 행
private
을protected
가져public
옵니다(
. 이는 메소드 정의를 식별합니다. - 추출방법명
- 메소드 이름을 찾으면 두 줄 뒤에 새 줄을 추가하고 추가하십시오.
여기서 "메소드 이름"은 2단계에서 추출된 이름입니다.Logger.add(Constants.METHOD_name, "name of the method")
아래 코드를 시도했습니다.
#! /bin/bash
arr=($(grep -E 'public|private|protected' DataServiceImpl.java | grep "(" | awk '{print$3}' | awk -F'(' '{print $1}'))
for (( i=0; i<${#arr[@]}; ++i )); do
sed "/${arr[$i]}(/{N;a Logger.add(Constants.METHOD_NAME,\"${arr[$i]}\");
}" DataServiceImpl.java > changedText.txt && mv changedText.txt DataServiceImpl.java
done
좋은 결과. 그러나 문제는 Logger.add
호출 행 뒤에 새 행을 삽입한다는 것입니다.
public String getProtocol()
예를 들어, 다음 줄을 추가하는 메서드가 있는 경우
Logger.add(Constants.METHOD_NAME,"getProtocol")
메소드 정의의 첫 번째 줄. 또한 호출되는 곳에 추가합니다 getProtocol()
.
이 상황을 피하는 방법은 무엇입니까? 우리가 이런 일을 할 수 있는 방법이 있나요?
#! /bin/bash
arr=($(grep -E 'public|private|protected' DataServiceImpl.java | grep "("))
for (( i=0; i<${#arr[@]}; ++i )); do
//search for match of array element. This would result in complete line till (
//If match found, add a line after two lines and add the below code.
//Extract 3rd column of array element. In public String getProtocol, we will get getProtocol
//Logger.add(Constants.METHOD_NAME, "extracted column")
done
Java 클래스 예:
public class DataServiceImpl
{
public String getProtocol()
{
return "https";
}
public String buildUrl()
{
String url = getProtocol()+"://www.google.com";
return url;
}
}
예상되는 결과:
public class DataServiceImpl
{
public String getProtocol()
{
Logger.add(Constants.METHOD_NAME,"getProtocol");
return "https";
}
public String buildUrl()
{
Logger.add(Constants.METHOD_NAME,"buildUrl");
String url = getProtocol()+"://www.google.com";
return url;
}
}
Logger.add
또한 아래에 줄을 추가하도록 지정 {
하고 정렬 뒤에 공백을 추가하도록 지정하는 방법이 있으면 도움이 될 것입니다 {
. 감사해요.
답변1
우리는 확장된 정규식 모드에서 GNU sed를 사용할 것입니다(정규식 작성을 어느 정도 쉽게 만들기 위해): 추신: 이것은 파서가 아니므로 때때로 일부 극단적인 경우가 발생할 수 있습니다.
$ sed -re '
/^\s*(public|private|protected)\s.*[(]/!b
h;s/\S+/\n/2;s/.*\n\s+//;s/[(].*//
s/.*/Logger.add(Constants.METHOD_NAME,"&");/
x;n;n;x;G
s/.*\n(\s*).*/\1&/
' file.java
방법: 관심 라인을 분리합니다. 그런 다음 메서드 이름을 가져와 원하는 로깅 용어로 장식합니다. 그 후 두 줄을 건너뛰고 인쇄합니다.
답변2
예를 들어 GNU awk를 사용하여 세 번째 인수를 match(), gensub() 및 \s/\S 약어로 일치시키는 것과 같이 awk를 사용하는 것이 더 간단하고, 더 깨끗하고, 더 이식성이 뛰어납니다.
$ cat tst.awk
match($0,/(private|protected|public).*\s(\S+)\s*\(/,a) {
methodName = a[2]
lineNr = NR+2
}
NR == lineNr {
indent = gensub(/\S.*/,"",1)
printf "%sLogger.add(Constants.METHOD_NAME,\"%s\");\n", indent, methodName
lineNr = 0
}
{ print }
.
$ awk -f tst.awk file
public class DataServiceImpl
{
public String getProtocol()
{
Logger.add(Constants.METHOD_NAME,"getProtocol");
return "https";
}
public String buildUrl()
{
Logger.add(Constants.METHOD_NAME,"buildUrl");
String url = getProtocol()+"://www.google.com";
return url;
}
}
또는 모든 UNIX 시스템의 모든 쉘에서 awk를 사용하십시오.
$ cat tst.awk
/(private|protected|public).*\(/ {
methodName = $0
sub(/[[:space:]]*\(.*/,"",methodName)
sub(/.*(private|protected|public).*[[:space:]]/,"",methodName)
lineNr = NR+2
}
NR == lineNr {
indent = $0
sub(/[^[:space:]].*/,"",indent)
printf "%sLogger.add(Constants.METHOD_NAME,\"%s\");\n", indent, methodName
lineNr = 0
}
{ print }
.
$ awk -f tst.awk file
public class DataServiceImpl
{
public String getProtocol()
{
Logger.add(Constants.METHOD_NAME,"getProtocol");
return "https";
}
public String buildUrl()
{
Logger.add(Constants.METHOD_NAME,"buildUrl");
String url = getProtocol()+"://www.google.com";
return url;
}
}