2

我正在尝试做的是在大量源文件中搜索特定模式,并在该模式的基础上放入另一个表达式。我正在查看的文件都具有相同的扩展名 *.F90。我的第一步是使用 grep 并找到那些包含分配但未分配的文件的所有行,所以我有:

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 是一个字母数字字符串,替换后出现在多个位置。它是被分配的数组的名称。如果有人能给我提示如何做到这一点,我将不胜感激。我被卡住了,不知道该怎么做。

4

2 回答 2

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 中的匹配行并使用allocatedon 跳过行。原始文件将被称为 *.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*abc用第一组替换最后一场比赛b
  • /^[az]*$/t 如果b匹配^[a-z]*$,则跳转到脚本末尾
  • xe*x*更改保持空间abc和模式空间b
  • p*p*打印图案空间b
于 2013-01-10T22:28:27.127 回答
1
cat old_file.txt | sed 's/allocate *( *\([a-zA-Z0-9_]*\)/If( allocated(\1) ) deallocate(\1)\
allocate(\1/' > new_file.txt
于 2013-01-10T22:36:52.160 回答