Analisa um arquivo de texto e imprime em um novo formato

1

Estou tentando aprender analisadores de arquivos usando o shell script e tenho meu arquivo de entrada input.txt as

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

Existe uma maneira de analisar o input.txt acima para o meu formato desejado, que se parece com esse arquivo output.txt output:

0,int, A[4], 0, 16
1,char, B[16], 16,31
2,long int, C[2], 32, 8 
    
por ven 08.04.2017 / 22:36

3 respostas

2

Sua entrada parece ser semelhante a C, então seria melhor, em teoria, analisá-la com um analisador C. Se você usa expressões regulares, mesmo para tarefas simples, você tem que lidar com espaços variados, entradas de várias linhas, etc. O problema é que os analisadores C não analisam comentários e, aparentemente, você deseja fazer isso.

Aqui está um script perl que fornece a saída esperada para sua amostra.

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

Se você salvar este script como script.pl na pasta em que input.txt é, use-o como tal:

./script.pl < input.txt > output.txt
    
por 08.04.2017 / 23:49
0

Uma alternativa awk sem regex:

$ 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

Pitfall:

$ 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
    
por 09.04.2017 / 02:40
0
perl -lane '
   /^\s*\/\*/ and $,=",",next;
   print $a++,join ", ", grep /./, map { m!^/\*+\K(\S*)|([^*]*)(?=\*+/$)|(.+[^;]);?$! } @F
'
    
por 09.04.2017 / 09:23