쉘 스크립트를 사용하여 파일 파서를 배우려고 하는데 입력 파일
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
'