Анализ текстового файла и вывод его в новом формате

Анализ текстового файла и вывод его в новом формате

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

 int A[4];   /* 0  16*/
 char B[15];  /* 16 31*/
 /* Padding may be required here */
 long int C[2]; /*32  8*/

Есть ли способ преобразовать вышеизложенное input.txtв нужный мне формат, который выглядит как этот output.txtвыходной файл:

0,int, A[4], 0, 16
1,char, B[16], 16,31
2,long int, C[2], 32, 8 

решение1

Ваш ввод, похоже, написан на языке C, поэтому теоретически было бы лучше разобрать его с помощью парсера C. Если вы используете регулярные выражения, даже для простых задач, вам придется иметь дело с различными пробелами, многострочным вводом и т. д. Проблема в том, что парсеры C не разбирают комментарии, а вы, по-видимому, хотите это сделать.

Вот скрипт Perl, который выдает ожидаемый результат для вашего примера.

#!/usr/bin/perl -n
#
BEGIN { $i = 0; }

if (m!^\s*(.+)\s+([^ ]+);\s*/\*\s*(\d+)\s*(\d+)\s*\*/\s*$!)
{
    print "$i,$1,$2,$3,$4\n";
    $i+=1
}

Если вы сохраните этот скрипт script.plв той же папке, где input.txtон находится, используйте его следующим образом:

./script.pl < input.txt > output.txt

решение2

Альтернатива awk без регулярных выражений:

$ echo "int A[4];   /* 0  16*/" |awk '{gsub(/[/*;]/,"");for (i=1;i<=NF;i++) printf("%s, %s", (i==1?NR-1:""),(i==NF?$i"\n":$i))}'
#Output:
0, int, A[4], 0, 16

Подводная ловушка:

$ echo "long int C[2]; /*32  8*/" |awk '{gsub(/[/*;]/,"");for (i=1;i<=NF;i++) printf("%s, %s", (i==1?NR-1:""),(i==NF?$i"\n":$i))}'
#Output
0, long, int, C[2], 32, 8

решение3

perl -lane '
   /^\s*\/\*/ and $,=",",next;
   print $a++,join ", ", grep /./, map { m!^/\*+\K(\S*)|([^*]*)(?=\*+/$)|(.+[^;]);?$! } @F
'

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