Обработка текста для извлечения структурных полей

Обработка текста для извлечения структурных полей

Например, я пытаюсь извлечь поля из структуры.

  typedef struct newstruct {
  long id;            
  uint32_t vtid;      
  struct HN* next;
} HashNode;

Я хочу использовать sed/awk для извлечения имени структуры, за которым следуют поля с разделителем, например

newstruct HashNode: long id, uint_32 vtid, struct HN* next

решение1

Это довольно просто с awk, возможно, выполнимо с sed.

С awk, у вас будет состояние, которое устанавливается/сбрасывается на каждой typedefстроке и завершается на каждой строке правой фигурной скобкой. Подходящий awkскрипт будет выглядеть так

BEGIN {
    state = 0;
    typedef="";
    fields="";
}
/typedef[ ]+struct/{
    state = 1;
    typedef=$3;
    next;
}
/}.*;/ {
    if (state != 0) {
        sub("^.*}[  ]*","",$0);
        sub(";","",$0);
        sub(",$","",fields);
        printf "%s %s: %s\n", typedef, $0, fields;
        state = 0;
        fields = "";
        typedef = "";
    }
    next;
}
(state == 1){ 
    gsub("[     ]+"," ", $0);
    gsub(";",",",$0);
    fields = fields $0;
    next;
}

где скобки [и ]заключают пробел и табуляцию (чтобы сделать его переносимым). Скрипт состоит из четырех частей:

  1. действие BEGINинициализирует переменные (это не обязательно, но некоторые awk делают немного другие вещи с неинициализированными переменными)
  2. шаблон, соответствующий строке с typedef, за которым следуют пробел(ы) и слово struct. Это ожидает не менее 3 полей в строке, используя третье в качестве имени typedef.
  3. шаблон, соответствующий закрывающей фигурной скобке. На всякий случай, если в вашем файле есть что-то еще, действие проверяет, было ли stateустановлено. $0Текущая строка. Первая подстановка обрезает все перед интересующим нас словом, а вторая обрезает точку с запятой после него. Третья подстановка изменяет запятую после переменной, fieldsкоторая пришла из 4-го действия (ниже), на пустую строку.
  4. шаблон, соответствующий всем остальным линиямкогда stateустановлено. Как и предыдущее действие, это действие использует замену для удаления ненужных частей, сначала сокращая несколько пробелов до одного, а затем изменяя конечную точку с запятой на запятую.

Назовите этот файл foo.awkи ваши входные данные foo.in, чтобы использовать awk следующим образом:

awk -f foo.awk <foo.in

Если вы хотите сопоставить строки следующим образом:

struct foo {

скорее, чем

typedef struct foo {

тогда шаблон может быть написан

/^([  ]*typedef)?[  ]+struct[  ]+/{

(опять же, с буквальным пробелом и табуляцией в квадратных скобках). Скобки обозначаютгруппаа вопросительный знак ?говорит, что это нужно повторить ноль или более раз. ({на линии фактически обозначает началодействие, но я оставил его там, чтобы он соответствовал строке в данном скрипте).

Дальнейшее чтение:

решение2

sed -rn '
/typedef struct ([[:alnum:]_]+)\s+\{/!b
s//\1/; h
:X
n 
/}\s+([[:alnum:]_]+)/{
    s//\1/
    H
    g
    s/;//g
    s/(.*)\n(.*)\n(.*)\n(.*)\n(.*)/\1 \5: \2, \3, \4/
    p;b
}
s/\s*(.+);\s*/\1/
H
bX
' file

newstruct HashNode: long id, uint32_t vtid, struct HN* next

Связанный контент