格式化函数使用sed调用语法

时间:2019-01-09 10:41:36

标签: bash sed parentheses

我想在某些fortran程序中格式化函数调用的语法,但找不到满足我需要的方法。

源代码中可能遇到的语法可能是:

func_example( x,y,z )
other_func_example(x,y,z, t)
another_one( x,y )
...

我需要的语法是:

func_example(x, y, z)
other_func_example(x, y, z, t)
another_one(x, y)
...

我找到了一种sed解决方案,可以完全消除花括号之间的空格:

echo -e "function{x,y,z}\n function{ x,y,z}\n function{x,y,z }\n function{ x,y,z }" 
| sed -e '/{/,/}/{s#\s*##g}'

这提供了:

function{x,y,z}
function{x,y,z}
function{x,y,z}
function{x,y,z}

这接近我的需求,但仍然存在问题:

  • 不适用于标准括号。我应该以一种无法企及的方式逃避他们。
  • 逗号后不留空格

在此方面,我将不胜感激。在我看来,Sed是最好的选择。我也可以接受任何完整的bash或awk解决方案,但是我想避免使用perl,因为我对此几乎一无所知。

3 个答案:

答案 0 :(得分:2)

以下内容:

echo 'function( x,y,z )
function(x,y,z)
function(x, y,z)' |
sed 's/\(function\)([[:space:]]*\([a-z]*\)[[:space:]]*,[[:space:]]*\([a-z]*\)[[:space:]]*,[[:space:]]*\([a-z]*\)[[:space:]]*)/\1(\2, \3, \4)/'

输出:

function(x, y, z)
function(x, y, z)
function(x, y, z)

它:

  1. function([a-z]*,[a-z]*,[a-z]*)与所有令牌之间的任意数量的[[:space:]]*空白字符(空格,制表符)匹配。
  2. 使用sed的\(...\)记住函数名称和参数名称
  3. 然后输出带有空格和逗号\1(\2, \3, )
  4. 的令牌
  5. 请注意,对于function(,,)
  6. 之类的奇怪输入也可以进行这种工作
  7. 如果要格式化某些C代码,请使用astyleindent或其他为此创建的实用程序。

答案 1 :(得分:0)

如果要先删除逗号周围的空格,可以使用

...  | sed -r 's/([(,]) */\1/g; s/ ([),])/\1/g; s/,/, /g'

替代方法:您可以使用tr或简单

开始删除所有空格。
...  | sed 's/ //g; s/,/, /g'

答案 2 :(得分:0)

我发现了一种awk解决方案,它可能不是最聪明的解决方案,但它适用于任何数量的昏迷。这个想法是生成一个包含一些要启动的sed命令的脚本。 我愿意分享它,以防对某些读者有帮助。

输入测试文件:

some_func(x, y,z)
some_func_a(x, y, z, t )
some_func_b(x,y,z)
some_func_z(x, y , z)
some_func(x, y , z )
! some comment
some_func( x, y)
some_func_1(x)
some text
some_func(x, z, a, b,e)
some_func_da(x, y,d, z)
some_func_bla( x, y, z)
some_text without parenthesis

我遇到的脚本如下:

while read line
do
    # Gets what's in parenthesis and the function name
    in_par=$(echo $line|awk -F "[()]" '/\(/{print "(" $2 ")" }')
    func_name=$(echo $line|awk -F "[()]" '/\(/{print $1}')
    # Formats to my desired format
    in_par_mod=$(echo $line|awk -F "[()]" '/\(/{print $2}'|awk '{ gsub (" ", "", $0); print}'|awk 'BEGIN{FS=","; OFS=", "} {$1=$1; print "(" $0 ")"}')
    # Re-buils full patterns
    in_name=$func_name$in_par
    mod_name=$func_name$in_par_mod
    printf " Before : %-30s  After : %-30s \n" "$in_name" "$mod_name"
    # Generating script to be launched
    if [ ! -z "$in_name" ]
    then
        printf "sed -i 's/%s/%s/g' %s \n " "$in_name" "$mod_name" "$in_file" >> sed_script.sed
    else
        printf "Line contains nothing to change \n"
    fi
done < $in_file

运行它会产生:

 Before : some_func(x, y,z)               After : some_func(x, y, z)
 Before : some_func_a(x, y, z, t )        After : some_func_a(x, y, z, t)
 Before : some_func_b(x,y,z)              After : some_func_b(x, y, z)
 Before : some_func_z(x, y , z)           After : some_func_z(x, y, z)
 Before : some_func(x, y , z )            After : some_func(x, y, z)
Line contains nothing to change
 Before : some_func( x, y)                After : some_func(x, y)
 Before : some_func_1(x)                  After : some_func_1(x)
Line contains nothing to change
 Before : some_func(x, z, a, b,e)         After : some_func(x, z, a, b, e)
 Before : some_func_da(x, y,d, z)         After : some_func_da(x, y, d, z)
 Before : some_func_bla( x, y, z)         After : some_func_bla(x, y, z)
Line contains nothing to change
Line contains nothing to change

并生成以下脚本:

sed -i 's/some_func(x, y,z)/some_func(x, y, z)/g' in.txt
sed -i 's/some_func_a(x, y, z, t )/some_func_a(x, y, z, t)/g' in.txt
sed -i 's/some_func_b(x,y,z)/some_func_b(x, y, z)/g' in.txt
sed -i 's/some_func_z(x, y , z)/some_func_z(x, y, z)/g' in.txt
sed -i 's/some_func(x, y , z )/some_func(x, y, z)/g' in.txt
sed -i 's/some_func( x, y)/some_func(x, y)/g' in.txt
sed -i 's/some_func_1(x)/some_func_1(x)/g' in.txt
sed -i 's/some_func(x, z, a, b,e)/some_func(x, z, a, b, e)/g' in.txt
sed -i 's/some_func_da(x, y,d, z)/some_func_da(x, y, d, z)/g' in.txt
sed -i 's/some_func_bla( x, y, z)/some_func_bla(x, y, z)/g' in.txt

对于改进此方法,我仍将不胜感激。