提取方法名称并将其添加到记录器作为方法的第一行

提取方法名称并将其添加到记录器作为方法的第一行

我有一个要求,需要在方法的第一行记录器中添加Java方法名称。

我正在尝试以下方法。

  1. 获取带有关键字privateprotectedpublic和字符的行(。这将识别方法定义。
  2. 提取方法名称
  3. 找到方法名后,在2行后添加新行,并添加
    Logger.add(Constants.METHOD_name, "name of the method")
    
    其中“方法名称”是在步骤 2 中提取的名称。

我已经尝试过下面的代码。

#! /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(在某种程度上使正则表达式的编写易于处理): P.S:这不是一个解析器,因此预计有时会出现一些极端情况。

$ 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

使用 awk 会更简单、更清晰、更可移植等,例如使用 GNU awk 将第三个参数匹配到 match()、gensub() 和 \s/\S 简写:

$ 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 机器上的任何 shell 中使用任何 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;
     }
}

相关内容