Синтаксис вызова форматных функций с помощью sed - PullRequest
0 голосов
/ 09 января 2019

Я хотел бы отформатировать синтаксис вызовов функций в некоторых программах на Фортране и не могу найти подход, удовлетворяющий моим потребностям.

Возможный синтаксис, встречающийся в исходном коде, может быть:

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}

Это близко к тому, что мне нужно, но есть еще проблемы:

  • Не будет работать со стандартными скобками. Я должен сбежать от них так, как не могу.
  • не оставляет пробела после запятых

Буду признателен за любую помощь в этом. Сед кажется мне лучшим вариантом. Я также принял бы любое полное решение bash или awk, но я бы хотел избежать использования perl, так как я почти ничего не знаю об этом.

Ответы [ 3 ]

0 голосов
/ 09 января 2019

Если вы хотите сначала удалить пробелы вокруг запятых, вы можете использовать

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

Альтернатива: Вы можете начать удалять все пробелы с tr или просто

...  | sed 's/ //g; s/,/, /g'
0 голосов
/ 10 января 2019

Я нашел решение 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

Я все равно буду благодарен за любую помощь или комментарий, чтобы улучшить этот метод.

0 голосов
/ 09 января 2019

следующее:

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. Обратите внимание, что он также будет работать для странных входов, таких как function(,,)
  5. Если вы форматируете некоторый код на C, используйте astyle или indent или другую утилиту, созданную для этого.
...