Analysieren Sie eine Textdatei und geben Sie sie in einem neuen Format aus

Analysieren Sie eine Textdatei und geben Sie sie in einem neuen Format aus

Ich versuche, Dateiparser mithilfe von Shell-Skripten zu lernen, und ich habe meine Eingabedatei input.txtals

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

Gibt es eine Möglichkeit, das Obige in das von mir gewünschte Format zu analysieren , das wie diese Ausgabedatei input.txtaussieht :output.txt

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

Antwort1

Ihre Eingabe scheint C-ähnlich zu sein, daher wäre es theoretisch besser, sie mit einem C-Parser zu analysieren. Wenn Sie reguläre Ausdrücke verwenden, müssen Sie selbst für einfache Aufgaben mit unterschiedlichen Leerzeichen, mehrzeiligen Eingaben usw. umgehen. Das Problem ist, dass C-Parser keine Kommentare analysieren und Sie dies anscheinend tun möchten.

Hier ist ein Perl-Skript, das die erwartete Ausgabe für Ihr Beispiel liefert.

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

Wenn Sie dieses Skript script.plin dem Ordner speichern, in dem input.txtes sich befindet, verwenden Sie es folgendermaßen:

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

Antwort2

Eine Awk-Alternative ohne reguläre Ausdrücke:

$ 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

Falle:

$ 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

Antwort3

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

verwandte Informationen