我一直在寻找一种方法来修改多个文件中包含特定单词/字符但不包含其他单词/字符的多行。更具体地说,a 希望将 fortran 文件中的所有变量声明从 转换real
为real(kind=r8)
.例如下面的行:
var= (var1*REAL(j)-var2*REAL(j)*var3)
REAL :: pwr10
INTRINSIC REAL
REAL(kind=r16) :: qr(n), qaorg, qx
REAL, DIMENSION(-1:nx, -1:ny) :: arg1
REAL(kind=r8) :: y3
应该变成:
var= (var1*REAL(j)-var2*REAL(j)*var3)
REAL(kind=r8) :: pwr10
INTRINSIC REAL
REAL(kind=r16) :: qr(n), qaorg, qx
REAL(kind=r8), DIMENSION(-1:nx, -1:ny) :: arg1
REAL(kind=r8) :: y3
我知道如何使用 grep 选择特定行,但不使用 sed 来修改它们。有人可以帮忙吗?
答案1
$ sed 's/REAL\([^(].*::\)/REAL(kind=r8)\1/' file
var= (var1*REAL(j)-var2*REAL(j)*var3)
REAL(kind=r8) :: pwr10
INTRINSIC REAL
REAL(kind=r16) :: qr(n), qaorg, qx
REAL(kind=r8), DIMENSION(-1:nx, -1:ny) :: arg1
REAL(kind=r8) :: y3
表达sed
方式
s/REAL\([^(].*::\)/REAL(kind=r8)\1/
将全部替换REAL
为REAL(kind=r8)
- 该字符串
REAL
后面没有紧跟着(
。 ::
同一条线上稍后有一个地方。
按照我编写的方式,该REAL
字符串可能会出现在该行的任何位置。如果单词首先出现在行上(行首和单词之间没有空格或任何内容),则使用^REAL
代替表达式中的第一个。REAL
答案2
perl -pe '/\h::\h/ && /^\h*REAL(?!\()\K/ and s//(kind=r8)/' input.txt
读作:
- 当每行都有一个空格分隔的“::”子字符串时。
- 关键字“REAL”从行首开始,前面可以选择空格,并且右侧看不到左括号。
- 当上述两个条件都满足时,我们进行替换。
- s//(kind=r8)/ 命令意味着使用上一次成功匹配的正则表达式并将其替换为 RHS 中的任何内容。
输出
var= (var1*REAL(j)-var2*REAL(j)*var3)
REAL(kind=r8) :: pwr10
INTRINSIC REAL
REAL(kind=r16) :: qr(n), qaorg, qx
REAL(kind=r8), DIMENSION(-1:nx, -1:ny) :: arg1
REAL(kind=r8) :: y3