我正在嘗試使用 shell 腳本學習文件解析器,我的輸入檔
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 解析器解析它會更好。如果您使用正規表示式,即使對於簡單的任務,您也必須處理不同的空格、多行輸入等。
這是一個 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
'