![解析文本文件并以新格式输出](https://linux22.com/image/109261/%E8%A7%A3%E6%9E%90%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E5%B9%B6%E4%BB%A5%E6%96%B0%E6%A0%BC%E5%BC%8F%E8%BE%93%E5%87%BA.png)
我正在尝试使用 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 解析器解析它会更好。如果您使用正则表达式,即使对于简单的任务,您也必须处理不同的空格、多行输入等。问题是,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
'