2016-10-13 4 views
0

Я с большим числом файлов C, которые структурированы следующим принципом:Поиск имен «главных» функций в файле C помощью Bash сценария

  • Все функции объявлены в файле C и имеют тип возврата int, double или void.
  • Все функции начинаются с «ksz_». Только функции используют это - ничто иное не использует «ksz_» в своих именах.
  • Файл содержит "основные" функции. Все поддерживающие функции используют имя своей основной функции, чтобы сформировать себя.
  • Потому что они были сделаны разными людьми, они довольно messly сделаны и пробелы, расположенных в различных местах:

rought визуализация будет (обратите внимание на пробелы):

int ksz_Print(...) 
{ 
... 
} 

void ksz_Print_Helper1 (...){ 
... 
} 
void ksz_Print_Helper2(...) { 
... 
} 
int ksz_Input(...){ 
... 
} 
double ksz_Input_Helper1 (...){ 
... 
} 

мне нужно найдите «основные» имена функций для каждого отдельного файла C, чтобы использовать их для другого алгоритма поиска. Поскольку эти файлы огромны (у них их более десятка тысяч строк), а их сотни, мне нужен сценарий Bash для этого.

В идеале этот сценарий будет извлечь только «основные» функции:

ksz_Print 
ksz_Input 

Что меня останавливает то, что я не могу думать о Regex моего Grep для извлечения функциональных линий. Я думаю, что его логика должна выглядеть следующим образом:

(пространства) (INT/поплавок/двойной) (пространства) (КСЗ _) (другие characers без пробелов) (пробелы) (открывающая скобка)

После того, что я думаю, Я извлечу слово, содержащее «ksz_» из каждой строки, с cut (после обрезки и удаления дубликатов пробелов).

И, наконец, мне нужно найти способ отфильтровать поддерживающие функции.

Но каков был бы мой первоначальный grep в этом скрипте?

+2

Я боюсь, что это будет очень трудно сделать с регулярными выражениями Рассматривали ли вы используя 'gtags',' ctags' или что-то подобное? –

+0

Что-то вроде 'grep -E '\ b (int | float | double) \ s + ksz_ [A-Za-z0-9] \ s * \ ('' должно вас начать. – coladict

+0

Я думаю, что регулярные выражения способны анализировать только обычные грамматики. В то время как C основан на контекстно-свободной грамматике. –

ответ

0

Если я правильно понимаю ваши требования правильно это должно сделать это:

[email protected] [~]# awk '/^[ \t]*(int|float|double)[ \t]+ksz_/ {print $2}' sample.txt 

Одна вещь, которую я не понимаю, о том, следует ли быть только один «_» после того, как КСЗ так, например, если «двойной ksz_Input_Helper1» не то, что вы хотите совместить. В регулярном выражении выше оно соответствует.

Я также решил пойти с awk, а не grep, поскольку вы сказали, что хотите только имя, которое выше awk печатает только второе поле, используя пробелы в качестве разделителя.Если вы все еще хотите использовать Grep это делает ту же задачу:

[email protected] [~]# egrep '^\s*(int|float|double)\s+ksz_' sample.txt 

Вот разбивка (примечание в AWK Я использую [\ т] вместо \ S, как я не мог заставить его признать \ s ]:

^ - match start of line 
\s* - match if there are 0 or more white spaces 
(int|float|double) - match int, float, OR double 
\s+ - match at least one whitespace 
ksz_ - match literal string "ksz_" 
+0

Как это выбрать «основные» функции из всех остальных? –

+0

Что делать, если имя функции отображается в другой строке, чем ее тип возврата? –

+0

Основываясь на том, что говорит OP, мне кажется, что они могут установить, что он не соответствует чему-либо, содержащему более одного подчеркивания ИЛИ использующему то, что я предоставил, и установил, что он не соответствует подчеркиванию после раздела «ksz_», поэтому ksz_ \ w [^ _] или что-то в этом роде. – Patino

0

Попробуйте использовать регулярное выражение, которое соответствует только части, которую вы хотите, и только печать, что:.

grep -oRE "(ksz_[a-zA-Z_]*\b)" * 
    -o - output only match 
    -R - recursive 
    -E - regex 
    [a-zA-Z_] - upper and lower case letters, underscore 
    \b - ending at word boundry 
+0

Это, похоже, не соответствует цели OP для выбора только «основных» функций. –

+0

@JohnBollinger - О, я вижу. Я скоро обновлю регулярное выражение – ventsyv

Смежные вопросы