GNU C LIB 库中有模式匹配这一章,除了威力非凡的正则表达式, Shell-Style Word Expansion 也是其中一节,介绍了另外一种模式匹配的思路。简单的说就是将输入的字符串,按照单词解析成一个wordexp_t类型的变量。这个变量本质是个矢量,她有we_wordc成员,表示有矢量成员的个数,换言之,就是解析成了几个单词。
注意,we_wodv这个指针数组,指向解析出来的每个字符串,为了防止内存泄露,执行完wordexp函数之后,需要执行wordfree来释放这些空间。既然牵扯到申请空间,所以wordexp这个函数有一种失败是空间不足,WRDE_NOSPACE。注意,纵然返回错误码是WRDE_NOSPACE,我们也需要执行wordfree,因为有可能已经分配了部分地址空间。
前面介绍的功能看好像这个函数平平无奇,不过就是把字符串拆分一下,基本就是按照单词查分而已,其实不然,这个函数功能还比较强大。
1 函数支持通配符扩展:
- #include <stdio.h>
- #include <stdlib.h>
- #include <wordexp.h>
- int
- main(int argc, char **argv)
- {
- wordexp_t p;
- char **w;
- int i;
- wordexp("ls -al *.c", &p, 0);
- w = p.we_wordv;
- for (i = 0; i < p.we_wordc; i++)
- printf("%s\n", w[i]);
- wordfree(&p);
- exit(EXIT_SUCCESS);
- }
- [beanl@localhost wordexp]$ gcc -o test test.c
- [beanl@localhost wordexp]$ ll
- total 12
- -rwxrwxr-x 1 beanl beanl 5095 Jun 9 11:31 test
- -rw-rw-r-- 1 beanl beanl 0 Jun 9 11:06 test2.c
- -rw-rw-r-- 1 beanl beanl 0 Jun 9 11:06 test3.c
- -rw-rw-r-- 1 beanl beanl 415 Jun 9 11:31 test.c
- [beanl@localhost wordexp]$ ./test
- ls
- -al
- test.c
- test2.c
- test3.c
看到了,我们用一个*.c,这个wordexp函数就解析出来了所有.c文件。
- #include <stdio.h>
- #include <stdlib.h>
- #include <wordexp.h>
- int
- main(int argc, char **argv)
- {
- wordexp_t p;
- char **w;
- int i;
- wordexp("ls -al *[0-9].c", &p, 0);
- w = p.we_wordv;
- for (i = 0; i < p.we_wordc; i++)
- printf("%s\n", w[i]);
- wordfree(&p);
- exit(EXIT_SUCCESS);
- }
- [beanl@localhost wordexp]$ ll
- total 12
- -rwxrwxr-x 1 beanl beanl 5099 Jun 9 11:34 test
- -rw-rw-r-- 1 beanl beanl 0 Jun 9 11:06 test2.c
- -rw-rw-r-- 1 beanl beanl 0 Jun 9 11:06 test3.c
- -rw-rw-r-- 1 beanl beanl 420 Jun 9 11:34 test.c
- [beanl@localhost wordexp]$ ./test
- ls
- -al
- test2.c
- test3.c
- [beanl@localhost wordexp]$
看到了用正则表达式 *[0-9].c,只解析了test2.c和 test3.c。
2 解析变量,进行替换
例如,我的环境变量SHELL为:declare -x SHELL="/bin/bash"
- #include <stdio.h>
- #include <stdlib.h>
- #include <wordexp.h>
- int
- main(int argc, char **argv)
- {
- wordexp_t p;
- char **w;
- int i;
- wordexp("ls -al $SHELL", &p, 0);
- w = p.we_wordv;
- for (i = 0; i < p.we_wordc; i++)
- printf("%s\n", w[i]);
- wordfree(&p);
- exit(EXIT_SUCCESS);
- }
- [beanl@localhost wordexp]$ ./test
- ls
- -al
- /bin/bash
- [beanl@localhost wordexp]$
当然,这个函数的功能还不限于此,我只是抛砖引玉,对这个函数感兴趣的筒子,可以参考GNU C LIB。
参考文献:
1
阅读(9185) | 评论(3) | 转发(0) |