我有一个要求,需要在方法的第一行记录器中添加Java方法名称。
我正在尝试以下方法。
- 获取带有关键字
private
、protected
或public
和字符的行(
。这将识别方法定义。 - 提取方法名称
- 找到方法名后,在2行后添加新行,并添加
其中“方法名称”是在步骤 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(在某种程度上使正则表达式的编写易于处理): 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;
}
}