awk - 文本文件中的算术替换

标签 awk sed

我有一个这样的文件:

id=1+5
id=1+9
id=25100+10
xyz=1+
abc=123456
conf_string=LMN,J,IP,25100+1,0,3,1

我想将 x+y 的实例替换为 (x+y) 的值。即1+5被6代替,25100+1被25001代替,以此类推。

我通过匹配像 /[:digit:]++[+digit:]+/ 这样的正则表达式来用 gawk 尝试这个
使用以下我可以替换一些实例。
gawk 'BEGIN {FS = "[=+,]"} ; /[:digit:]++[+digit:]+/ {print $1 "=" ($2 + $3)} ! /[:digit:]++[+digit:]+/ {print $0}' /tmp/1.txt 
id=6
id=10
id=25110
xyz=1+
abc=123456
conf_string=LMN,J,IP,25100+1,0,3,1

我不确定如何在上面的例子中匹配和替换 (25100+1)。理想情况下,我想提取 <number> + <number> 的所有实例并将其替换为总和。它永远是两个数字的总和。

最佳答案

使用 GNU awk :

$ awk 'BEGIN{r = @/([0-9]+)\+([0-9]+)/}
       { while(match($0, r, m)) sub(r, m[1] + m[2]) } 1' ip.txt
id=6
id=10
id=25110
xyz=1+
abc=123456
conf_string=LMN,J,IP,25101,0,3,1
  • r=@/([0-9]+)\+([0-9]+)/ 将正则表达式保存在一个变量中,[0-9] 将匹配所有数字
  • 如果正则表达式匹配,match($0, r, m) 将为真,匹配的部分将在 m 数组中可用
  • m[1] + m[2] 将两个数相加
  • 对于旧版本,使用 awk '{while(match($0, /([0-9]+)\+([0-9]+)/, m)) sub(/([0-9]+)\+([0-9]+)/, m[1] + m[2]) } 1' ip.txt 因为不支持在变量中保存正则表达式

  • 注意
  • [:digit:] 应该在字符类中使用 [[:digit:]]
  • ++ 应该是 +\+ 因为你打算第二个匹配 + 字面意义

  • 另见:How to coerce AWK to evaluate string as math expression?

    使用 perl 您可以简单地使用 e 标志来评估替换为代码
    perl -pe 's/(\d+)\+(\d+)/$1+$2/ge' ip.txt
    # or    
    perl -pe 's/\d+\+\d+/$&/gee' ip.txt
    

    关于awk - 文本文件中的算术替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62241101/

    相关文章:

    regex - 将 CPU 温度存储在变量中

    linux - 带组捕获的并行 sed

    file - sed 在多行匹配后追加

    linux - 将 Bash 参数传递给封装 AWK 命令的 Bash 变量

    bash跨多个字段查找非冗余数据

    sed - 如何编写一个 `sed` 脚本,用另一个文件的内容替换两个标记之间的文本

    bash - 使用 shell 脚本处理处理制表符分隔文件

    linux - 使用 sed 将每个单词的第三个字符括起来

    linux - Shell 编程变量不会进入 if 或 case 语句

    linux - unix 将文件列表连接到线上