Search code examples
bashsedparentheses

Format function calls syntax with sed


I would like to format the syntax of function calls in some fortran program and I can't find an approach fulfilling my needs.

The possible syntax encountered in the source code can be:

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

The syntax I need is exactly:

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

I found a sed solution that completely removes spaces between curly braces:

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}'

This provides:

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

This is close to what I need but there are still issues:

  • Won't work with standard parentheses. I should escape them in a way I can't get to.
  • Leaves no space after commas

I would appreciate any help on this. Sed seems to me as the best option. I would also accept any full bash or awk solution, but I'd like to avoid using perl as I know almost nothing about it.


Solution

  • I found an awk solution that is probably not the most clever one, but it works for any number of comas. The idea is to generate a script containing some sed commands to be launched. I share it in case it could be of any help for some reader.

    Input test file:

    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
    

    The script I came to looks like:

    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
    

    Running it yields:

     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
    

    And generates the following script:

    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
    

    I would still appreciate any help or comment to improve this method.