linux glob函数详解
glob库函数用于Linux文件系统中路径名称的模式匹配,即查找文件系统中指定模式的路径。注意,这不是正则表达式匹配,虽然有些相似,但还是有点差别。
glob函数原型
#include <glob.h>
int glob(const char *pattern, int flags,
int errfunc(const char *epath, int eerrno),
glob_t *pglob);
glob函数搜索匹配 函数pattern中的参数,如/*是匹配根文件下的所有文件(不包括隐藏文件,要找的隐藏文件需要从新匹配),然后会将匹配出的结果存放到 pglob,即第4个参数中,第二个参数能选择匹配模式,如是否排序,或者在函数第二次调用时,是否将匹配的内容追加到pglob中,等,第3个参数是查看错误信息用,一般置为NULL;
具体可以在终端下输入 man glob
实例1:
1 #include <stdio.h> 2 #include <glob.h> 3 4 int main(int argc, const char *argv[]) 5 { 6 glob_t buf; 7 int i; 8 glob("/dev/*",GLOB_NOSORT, NULL, &buf); 9 10 for(i=0; i < buf.gl_pathc; i++) 11 { 12 printf("buf.gl_pathv[%d]= %s \n", i, (buf.gl_pathv[i])); 13 } 14 15 globfree(&buf); 16 return 0; 17 } 18
实例2:
在linux编程中,有时候会用到批量处理文件。比如写一个上传工具,用户输入文件名,如果此时用户使用的是匹配的文件名,那么程序应该做到根据匹配字符串自动搜索符合要求的文件名的功能。
linux有一个glob函数,可以做到这一点,该函数位于头文件glob.h中
事例:
1 #include <iostream> 2 3 #include <string> 4 5 #include <glob.h> 6 7 using namespace std; 8 9 10 11 void print_gl(glob_t &gl) 12 13 { 14 15 for(int i=0;i<gl.gl_pathc;i++) 16 17 { 18 19 cout<<gl.gl_pathv[i]<<endl; 20 21 } 22 23 } 24 25 26 27 void test_glob(int argc , char **argv) 28 29 { 30 31 glob_t gl; 32 33 for(int i=1;i<argc;i++) 34 35 { 36 37 gl.gl_offs=0; 38 39 glob(argv[i],GLOB_TILDE,0,&gl); 40 41 print_gl(gl); 42 43 globfree(&gl); 44 45 } 46 47 } 48 49 50 51 int main(int argc,char **argv) 52 53 { 54 55 if(argc<2) 56 57 { 58 59 cout<<"<file name>"<<endl; 60 61 return 0; 62 63 } 64 65 66 67 test_glob(argc,argv); 68 69 return 0; 70 71 }
实例3:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include <glob.h> 6 7 static int test_fun(int, char *[]); 8 static void print_gl(glob_t *); 9 10 int main(int argc, char *argv[]) 11 { 12 if(argc > 1) 13 test_fun(argc, argv); 14 else 15 printf("./mytest {/"path list/"}/n"); 16 return 0; 17 } 18 19 static int test_fun(int argc, char *argv[]) 20 { 21 glob_t gl; 22 for(int i = 1; i < argc; ++i) { 23 gl.gl_offs = 0; 24 glob(argv[i], GLOB_TILDE, 0, &gl); 25 print_gl(&gl); 26 globfree(&gl); 27 } 28 return 0; 29 } 30 31 static void print_gl(glob_t *gl) 32 { 33 for(unsigned int i = 0; i < gl->gl_pathc; ++i) 34 printf("%s/n", gl->gl_pathv[i]); 35 printf("++++++++++++++++++++++/n"); 36 }
编译:
gcc -std=c99 -g -W -Wall -Wextra -o mytest main.c
执行示例:
./mytest "./*.cpp" "./*.h" "./make*" "~/p*/p?ng"
注意:上诉命令中引号是必需的,否则shell会将模式展开!
实例4:
用glob的递归调用可以找到系统任意路径的所有文件。如下例子:
1 #include <stdio.h> 2 #include <glob.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <unistd.h> 8 9 static int OpenDir(const char *buf) 10 { 11 int ret; 12 char path[50] = {0}; 13 char temp[50] = {0}; 14 char *tp = NULL; 15 glob_t globbuf; 16 struct stat fileinfo; 17 int i; 18 char *ptr = NULL,*last_ptr = NULL; 19 strcpy(path,buf); 20 if(buf[strlen(buf)- 1] == '/') 21 strcat(path,"*"); 22 else 23 strcat(path,"/*"); 24 if((ret = glob(path,GLOB_NOSORT,NULL,&globbuf)) != 0){ 25 if(GLOB_NOMATCH == ret) 26 return 0; 27 else 28 return -1; 29 } 30 strcpy(path,buf); 31 if(buf[strlen(buf)- 1] == '/') 32 strcat(path,".*"); 33 else 34 strcat(path,"/.*"); 35 36 if((ret = glob(path,GLOB_APPEND,NULL,&globbuf)) != 0){ 37 if(GLOB_NOMATCH == ret) 38 return 0; 39 else 40 return -1; 41 } 42 for(i = 0;i < globbuf.gl_pathc;i++){ 43 ret = lstat(globbuf.gl_pathv[i],&fileinfo); 44 if(ret != 0){ 45 perror("lstat()"); 46 return -1; 47 } 48 if(1 == S_ISDIR(fileinfo.st_mode)){ 49 printf("\n%s is directory!\n",globbuf.gl_pathv[i]); 50 strcpy(temp,globbuf.gl_pathv[i]); 51 tp = temp; 52 while((last_ptr = strsep(&tp,"/")) != NULL){ 53 ptr = last_ptr; 54 } 55 if((strcmp(ptr,".") == 0) || (strcmp(ptr,"..") == 0)) 56 continue; 57 ret = OpenDir(globbuf.gl_pathv[i]); 58 if(ret != 0){ 59 printf("*****opendir() error!\n"); 60 } 61 } 62 else 63 { 64 printf("%s\n",globbuf.gl_pathv[i]); 65 } 66 } 67 return 0; 68 } 69 int main(int argc, char *argv[]) 70 { 71 glob_t globbuf; 72 int ret ; 73 struct stat fileinfo; 74 int i; 75 if(argc != 2){ 76 printf("argument error!\n"); 77 } 78 ret = OpenDir(argv[1]); 79 if(ret != 0){ 80 printf("opendir() error!\n"); 81 return -1; 82 } 83 return 0; 84 }
执行如下命令获取当前路径中所有文件:
[tom@localhost glob]$ ./glob ./
./dir2 is directory!
./glob.c
./glob
./dir1 is directory!
./dir1/file2
./dir1/file1
./dir1/. is directory!
./dir1/.. is directory!
./. is directory!
./.. is directory!
可以看到 当前路径下有dir1 和dir2 两个目录,其中dir2为空目录,dir1中有file1和file2两个文件,.和..两个隐藏文件以及程序源码glob.c和可执行程序文件glob。
注意:
假设你有一个文件夹,你要删除里面类似这样命名的文件 :; ?1 t& z j3 M9 N9 r' D- t; g
/path/to/dir/000000 - Smooth Faker
/path/to/dir/000000 - Rubber Hocker8 w/ C( r5 S. v" P! w- N+ e% {
...S2nS2n q0 t2 w
, F/ r" _! \* ~: V6 k/ x( _
在 perl 里你可以用很多方法得到这样的文件列表(TIMTOWTDI),诸如opendir后grep, find函数,当然还有更容易让shell迷想起的glob函数。 不过关于glob函数,这里有个很大的陷阱,如果不注意他将可能导致灾难后果,比如:. i K" a. T% t ^
, s5 z. J8 R* t8 C
unlink glob("/path/to/dir/000000 - *");1 u' F2 |! P! P
看上去似乎没问题,但这个危险的操作可以删除你当前文件下的的所有文件。
; t; _HH ~
让我们仔细看文档, perldoc File::Glob :
Since v5.6.0, Perl’s CORE::glob() is implemented in terms of' Y3 R$ R- ^0 b9 |* h. j
bsd_glob(). Note that they don’t share the same
prototype--CORE::glob() only accepts a single argument. Due to
historical reasons, CORE::glob() will also split its argument on% e% t6 u- ] q' b9 \( q6 j7 W& O$ J0 N; U
whitespace, treating it as multiple patterns, whereas bsd_glob()/ iN! j# YN! j# Y }# g
considers them as one pattern.
也就是说,这里的 glob 操作变成了, File::Glob::bsd_glob("/path/to/dir/00000", "-", "*"), 你将会删掉'*'匹配的所有文件。解决办法是用双引号括起整个部分,或者使用File::Glob::bsd_glob。
- r- J" O9 \7 ?3 i( H
按理这个是已经在文档中说明了,不应该算是陷阱,不过如果你仅仅用 perldoc -f glob 查看,那么并没有类似的说明和警告而是让你转而看 File::Glob 的说明。(常常的)偷懒和想当然的结果就是,忽视了这里最大的一个可能引爆的漏洞。所以这里的建议是不使用glob而是使用File::Glob::bsd_glob
linux glob函数详解相关推荐
- linux下wait函数,Linux wait函数详解
wait和waitpid出现的原因 SIGCHLD --当子进程退出的时候,内核会向父进程SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) --子进程退出时,内核将 ...
- linux 信号处理函数详解
转自:http://blog.csdn.NET/sddzycnqjn/article/details/7285760 1. 信号概念 信号是进程在运行过程中,由自身产生或由进程外部发过来的消息(事件 ...
- linux时间函数详解
一.时间相关说明 格林威治时间表示0时区的标准时间.其他时区的时间和此标准时间均有时间差.UTC(Universal Time Coordinated)是世界协调时间,是格林威治时间在互联网中的表示方 ...
- linux socket函数详解,linuxSocket_函数.doc
垄话让蛤驻本扑缔蛙画乐谁啊绅驯钟鬼作娄醉龙嫂钠孝叔肛歼孽及蒂吐表蚕叉茂膏缮烫再熔汾帆帜钢姬苫云揣诊保绩判庞瞩芝揍蒲垃饿裔恍疗镊畏架浓谱极赤侨辆雀橱颓座寓卓皖森鬃香强孽饵讣蔽际狐颖钾妨壕托扯盐蛮它射图统 ...
- linux mmap 函数详解,Linux之mmap函数简介
本文主要讲述mmap 函数的使用,与驱动中 mmap 函数的实现 mmap 怎么使用,怎么实现,为什么 mmap 可以减少额外的拷贝? 下面简单详情. 一. mmap 的使用#include void ...
- linux mmap 函数详解,mmap函数详解与代码实操
icon1.jpg mmap 函数是 unix/linux下的系统调用. 当存在客户-服务程序中复制文件时候,其数据流如下,要经历四次数据复制,开销很大. image.png 果采用共享内存的方式,那 ...
- linux select函数详解
在Linux中,我们可以使用select函数实现I/O端口的复用,传递给 select函数的参数会告诉内核: •我们所关心的文件描述符 •对每个描述符,我们所关心的状态.(我们是要想从一个文件描述符中 ...
- Linux pause函数 详解
int pause(void); 作用:使调用进程(线程)进入休眠状态(就是挂起):直到接收到信号且信号函数成功返回 pause函数才会返回 返回值:始终返回-1 示例代码: #include < ...
- linux symlink 函数,详解C语言中symlink()函数和readlink()函数的使用
C语言symlink()函数:建立文件符号连接头文件: #include 定义函数: int symlink(const char * oldpath, const char * newpath); ...
最新文章
- AIX系统文件安全性方面的几点考虑
- VS2008显示代码行号
- Qt程序打包发布方法(使用官方提供的windeployqt工具)
- PostgreSQL学习笔记8之索引
- spring什么版本支持java8,与Java 11兼容的最低Spring版本
- [Java基础]HashSet集合概述和特点
- oracle更新blol字段超长,oracle - 将对象值插入表PL / SQL而无需指定属性 - 堆栈内存溢出...
- 刘光聪 | TensorFlow:揭示多语言编程的奥秘
- 讨论一个比较有意思的业务需求
- mysql 5.6.41-winx64,Mysql-5.6.41内存爆满一例
- 把数据库中的数据制作成Excel数据
- 矩阵论复习笔记:矩阵直积及其应用
- Java 条形码 二维码 的生成与解析
- vs2008/vs2010新手快速入门必读教程
- pil库修改图片大小_利用pillow库(PIL)批量修改图片尺寸
- 数据库查询-分数排名
- QQ小游戏接入问题:Uncaught TypeError: wx.saveFile is not a function
- .jar.LASTUPDATED问题解决
- 数据提取方法-数据提取的概念和数据的分类
- 企业为什么要通过直播来做营销呢?
热门文章
- hdu-1576(A/B)
- 1.svn无法连接,2.svn日志无法显示,3.日志无法修改
- 协程的三种同步方式Channel、Mutex、WaitGroup
- 面向对象和面向过程,python中的类class,python中程序的入口——main方法,
- python模块、字符编码、文件读写
- 腾讯云 wdcp ip:8080打不开,wdcp phpmyadmin打不开
- 微信公众平台前端开发技巧分享
- Centos6.5环境中安装vsftp服务
- 【转】获取命名空间、类名、方法名
- c# select标签绑定枚举,并以Description做Text显示