使用sed搜索大量文件以获取特定字符串并替换它

时间:2013-01-10 22:09:20

标签: bash sed

我要做的是搜索特定模式的大量源文件,并将此模式的另一个表达式置于其中。我正在查找的文件都具有相同的扩展名* .F90。 我的第一步是使用grep并找到包含allocate但未分配的那些文件的所有行,所以我有:

grep –I “ allocate *(” *.F90 | grep –v allocated

我遇到的第一个问题是括号可能前面有一个或多个空格。我可以

 allocate( 
 or allocate ( 
 or allocate  (  

这就是我在grep命令中需要“*”的原因。 然而,一般规则(除了空格)说,分配后面跟着“(”而不是正在分配的东西。所以我有:

allocate ( array_name ( .... 

这些空格也是可选的 所以我想要做的是找到这个字符串,并在其前面加上以下内容:

If( allocated(array_name) ) deallocate(array_name)

并且在下一行之后,我希望得到原始字符串allocate(array( … .

请注意,array_name是一个字母数字字符串,在替换后出现在多个位置。它是被分配的数组的名称。 如果有人能给我一个如何做到这一点的提示,我将非常感激。我被困住了,不知道怎么做。

2 个答案:

答案 0 :(得分:2)

我认为您的意思是要将allocate ( array_name )替换为If( allocated(array_name) ) deallocate(array_name) allocate ( array_name )

在GNU或BSD sed中,您可以执行以下操作:

sed -i.bk -e '/allocated/t' \
  -e 's/allocate *( *\([A-Za-z0-9_]*\) *)/If( allocated(\1) ) deallocate(\1) &/' \
  *.F90

这将搜索并替换* .F90中的匹配行,并跳过allocated开启的行。原始文件将被称为* .F90.bk。

正如@Anders Johansson所提到的,可能存在其他情况,分配的参数不是字母 - 下划线,那么你可以在搜索和替换之前搜索它:

for i in *.F90; do
    echo "$i"
    sed -n '/.*allocate *( *\([^ )]*\) *).*/{h; s//\1/; /^[A-Za-z0-9_]*$/t
        x; p;}' "$i"
done

(注意t之后的换行符,BSD sed将t之后的所有内容解释为标签)。在bash中按ctrl + v ctrl + j在命令行上输入换行符。

  • /a\(b\)c/找到匹配字符串
  • 的行
  • h * h *将匹配abc保留到保留空间
  • s//\1/ * s * ubstitute上一场比赛abc与第一组b
  • / ^ [a-z] * $ / t如果b^[a-z]*$匹配,则分支到脚本结束
  • x e * x *更改保留空间abc图案空间b
  • p * p * rint pattern space b

答案 1 :(得分:1)

cat old_file.txt | sed 's/allocate *( *\([a-zA-Z0-9_]*\)/If( allocated(\1) ) deallocate(\1)\
allocate(\1/' > new_file.txt