我有一个文件Builder.java,其中包含以下几行:
public class Builder{
@Override
public void setCallId(long value) {
set4ByteField(value, 48);
setLogtype(1);
setVerify("ABAB");
}
public void setOriginCallId(long value) {
set8ByteField(value, 52);
}
public void setDateTimeYear(int value) {
set2ByteField(value, 60);
}
...
Run Code Online (Sandbox Code Playgroud)
然后我只想将大于 50 的数字替换为数字 + 1,其他所有内容保持原样。结果:
public class Builder{
@Override
public void setCallId(long value) {
set4ByteField(value, 48);
setLogtype(1);
setVerifyflag("ABAB");
}
public void setOriginCallId(long value) {
set8ByteField(value, 53);
}
public void setDateTimeYear(int value) {
set2ByteField(value, 61);
}
....
}
Run Code Online (Sandbox Code Playgroud)
我尽力了,但写的脚本不起作用,例如:
cat Builder.java | awk -F'[,)]' '$2>50 {print $2+1}' > Builder.java
Run Code Online (Sandbox Code Playgroud)
增加绝对值大于 50 的所有数字。
perl -pe 's/\b(\d+)\b/$1>50 ? $1+1 : $1/ge' file
Run Code Online (Sandbox Code Playgroud)
该图案是数字(的序列\d+)与边界(\b),以便它不匹配的数量4在set4ByteField,例如。命令末尾的e标志允许将替换视为表达式,即捕获组上的三元表达式
。
增加所有大于 50 的数字。
perl -pe 's/(^|[^-])\b(\d+)\b/$1.($2>50 ? $2+1 : $2)/ge' file
Run Code Online (Sandbox Code Playgroud)
^|[^-]匹配数字序列左侧的行首或除连字符减号以外的任何字符。这排除了负数。
顺便说一句,您不应该同时写入文件和读取文件。您尝试在处理文件之前将其截断,因此您会得到一个空文件。要就地编辑文件,请使用 Perl 的-i标志(请参阅
命令行选项)。更好的是,-i.bak
使用.bak扩展名保存原始文件,以防出现问题。
你awk几乎是对的,但你想交替一个字段,然后打印整行。此外,输出字段分隔符也被删除,并手动添加了缺少的逗号和右括号:
awk 'BEGIN {FS="[,)]" ; OFS="" } /ByteField/ && $2 > 50 {$2=", "$2+1")"} ; 1' file
Run Code Online (Sandbox Code Playgroud)
如果1始终为 true,则始终打印该行(对于所有行) - 请注意,它必须在更改字段后完成。我添加了一个匹配项/ByteField/提高鲁棒性。
对于替换文件:与cat输出具有相同文件的命令的冗余和管道将中断。使用其他方法。例如
使用 GNU awk
awk -i inplace 'BEGIN ....' file
Run Code Online (Sandbox Code Playgroud)
带海绵
awk 'BEGIN ...' file | sponge file
Run Code Online (Sandbox Code Playgroud)
或者借助临时文件
awk 'BEGIN ...' file > file.alt
mv file.alt file
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
319 次 |
| 最近记录: |