sed命令 - 将一行中的2个单词替换为2个单词,同时保留第二个单词的缩进

时间:2017-08-27 03:58:59

标签: bash sed

我想在各种Fortran文件中替换以下循环的语法:

   do 40, k=0,size_z+1
    do 30, j=0,size_y+1
     write(5,1000,advance='no') (x0(i,j,k),i=0,size_x)
     write(5,999,advance='no') x0(size_x+1,j,k)
     write(5,*)
30  continue
    if(k.ne.(size_z+1)) then
     write(5,*)
    endif
40 continue

by:

   do k=0,size_z+1
    do j=0,size_y+1
     write(5,1000,advance='no') (x0(i,j,k),i=0,size_x)
     write(5,999,advance='no') x0(size_x+1,j,k)
     write(5,*)
    end loop
    if(k.ne.(size_z+1)) then
     write(5,*)
    endif
   end loop

我成功取代" do number," by" do"用:

sed "s/do\s[0-9]*,/do/g"

现在,我想替换" 30 continue"和" 40 continue" by" end loop"设置" end loop"的缩进;等于" continue"的缩进(相对于" do"与此对应的循环关键字" continue"(参见上面的想要替换)。

不幸的是,我不是专家,可以通过良好的缩进来获得这个结果。

欢迎任何帮助,问候

更新1

在我的文件中,我意识到我有这样的行:

1000 format(1000(f15.11,1x))
1001 format('   Convergence = ',f11.9,' after ',i9,' steps ')
1002 format('   Wall Clock = ',f15.6)

所以我想使用给定的解决方案,同时排除以数字开头并包含" format("

的替换行

我不知道如何在保持上述解决方案有效的同时排除此模式。我试过了:

sed -e 's:\(\s*do\s*\)[0-9]*,\s*:\1:' \
    -e '/^[0-9]/ s:[0-9 ]: :g' \
    -e '/format(/!s:continue:end loop:'

但这不起作用。我明白了:

     format(    (f  .  , x))
     format('   Convergence = ',f  . ,' after ',i ,' steps ')
     format('   Wall Clock = ',f  . )

由于

1 个答案:

答案 0 :(得分:0)

使用sed如下。

sed -e 's:\(\s*do\s*\)[0-9]*,\s*:\1:' \
    -e '/continue/ s:[0-9 ]: :g' \
    -e 's:continue:end loop:' infile
  1. 's:\(\s*do\s*\)[0-9]*,\s*:\1:'
    • \s*匹配任何零个或多个空格
    • \s*do\s*匹配do,其后面有零个或多个空格,后跟
    • [0-9]*,\s*零个或多个数字,逗号,和零个或多个空格
    • \(...\)\(\s*do\s*\)匹配为\1作为back reference
    • 的一组匹配项
  2. '/continue/ s:[0-9 ]: :g'

    • /continue/匹配行,如果有继续,则
    • s:[0-9 ]: :g'用一个空格替换每个数字,包括空格本身,这将保留这些行的缩进
  3. 's:continue:end loop:'continue替换为end loop

  4. 您可以使用任何字符作为分隔符,而不是:,这不是字符串的一部分,或者您可以将其转义。