我正在尝试修改.java
包含类似以下字符串的众多文件中的 Java 源代码:
private static final Height biomeHeight = new Height(0.1F, 0.2F);
有超过 75 个,我想找到一种方法来自动化0.1F 和 0.2F 值加倍在多个字符串中。请注意,每个文件中的 0.1F 和 0.2F 值是不同的。
例如,在一个文件中,字符串可能是这样的:
private static final Height biomeHeight = new Height(0.2F, 0.1F);
在这种情况下,我希望它是:
private static final Height biomeHeight = new Height(0.4F, 0.2F);
我怎样才能实现这一自动化?
答案1
我假设您要更改的所有行都以字符串开头private static final Height biomeHeight = new Height
。如果是,那么您可以使用awk
:
awk -F'[(,)]' '$1=="private static final Height biomeHeight = new Height"\
{$0=$1"("$2*2"F, "$3*2"F);";}1' file
解释:
-F'[(,)]'
将分隔符设置awk
为字符(
,)
并且,
我们在awk
字段 $2
和$3
$1=="..."
如果第一个字段等于字符串{$0=$1"("$2*2"F, "$3*2"F);";}
使用双倍的值重新格式化新字符串。
1
,1
末尾的那个单数相当于{print $0}
,因此打印整行(已编辑或未编辑)。
编辑:
上述awk
语句仅当行以 开头时才有效private static ...
。当有空格时,我们需要稍微修改一下:
awk -F'[(,)]' '$1~/[ ]*private static final Height biomeHeight = new Height/\
{$0=$1"("$2*2"F, "$3*2"F);";}1'
我已与你核实粘贴代码. 请参阅diff
:
$ diff file_old file_new
12c12
< private static final Height biomeHeight = new Height(8.0F, 0.025F);
---
> private static final Height biomeHeight = new Height(16F, 0.05F);
答案2
您可以考虑使用perl
例如
perl -pe 's/(?<=Height\()([0-9.]+)F(.+?)([0-9.]+)F(?=\);)/sprintf "%sF%s%sF",2*$1,$2,2*$3/e' file.java
和是(?<=Height\()
(?=\);)
零长度断言或者环视将匹配限制在这些分隔符之间的特定区域,然后使用提取数值捕获组然后可以使用(evaluate) 修饰符在替换表达式中操作其值$1
...。$3
sprintf
/e
要递归应用,可以使用find
以下命令:
find . -name '*.java' -execdir perl -i'.bak' -pe 's/(?<=Height\()([0-9.]+)F(.+?)([0-9.]+)F(?=\);)/sprintf "%sF%s%sF",2*$1,$2,2*$3/e' {} \;
在您的测试文件上运行它:
$ perl -i'.bak' -pe 's/(?<=Height\()([0-9.]+)F(.+?)([0-9.]+)F(?=\);)/sprintf "%sF%s%sF",2*$1,$2,2*$3/e' bop.txt
然后使用diff
确认替换
$ diff bop.txt.bak bop.txt
12c12
< private static final Height biomeHeight = new Height(8.0F, 0.025F);
---
> private static final Height biomeHeight = new Height(16F, 0.05F);