Analizar un archivo de texto y generarlo en un nuevo formato

Analizar un archivo de texto y generarlo en un nuevo formato

Estoy intentando aprender analizadores de archivos usando un script de shell y tengo mi archivo de entrada input.txtcomo

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

¿Hay alguna manera de analizar lo anterior input.txten el formato deseado que se parece a este output.txtarchivo de salida?

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

Respuesta1

Su entrada parece ser similar a C, por lo que, en teoría, sería mejor analizarla con un analizador de C. Si usa expresiones regulares, incluso para tareas simples, tendrá que lidiar con espacios variables, entradas de varias líneas, etc. El problema es que los analizadores de C no analizan comentarios y aparentemente usted quiere hacerlo.

Aquí hay un script en Perl que proporciona el resultado esperado para su muestra.

#!/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
}

Si guarda este script como script.plen la carpeta donde input.txtestá, úselo como tal:

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

Respuesta2

Una alternativa awk sin expresiones regulares:

$ 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

Trampa:

$ 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

Respuesta3

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

información relacionada