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:
#include <stdio.h>
#include <glob.h> int main(int argc, const char *argv[])
{
glob_t buf;
int i;
glob("/dev/*",GLOB_NOSORT, NULL, &buf); for(i=; i < buf.gl_pathc; i++)
{
printf("buf.gl_pathv[%d]= %s \n", i, (buf.gl_pathv[i]));
} globfree(&buf);
return ;
}
实例2:
在linux编程中,有时候会用到批量处理文件。比如写一个上传工具,用户输入文件名,如果此时用户使用的是匹配的文件名,那么程序应该做到根据匹配字符串自动搜索符合要求的文件名的功能。
linux有一个glob函数,可以做到这一点,该函数位于头文件glob.h中
事例:
#include <iostream> #include <string> #include <glob.h> using namespace std; void print_gl(glob_t &gl) { for(int i=;i<gl.gl_pathc;i++) { cout<<gl.gl_pathv[i]<<endl; } } void test_glob(int argc , char **argv) { glob_t gl; for(int i=;i<argc;i++) { gl.gl_offs=; glob(argv[i],GLOB_TILDE,,&gl); print_gl(gl); globfree(&gl); } } int main(int argc,char **argv) { if(argc<) { cout<<"<file name>"<<endl; return ; } test_glob(argc,argv); return ; }
实例3:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <glob.h> static int test_fun(int, char *[]);
static void print_gl(glob_t *); int main(int argc, char *argv[])
{
if(argc > )
test_fun(argc, argv);
else
printf("./mytest {/"path list/"}/n");
return ;
} static int test_fun(int argc, char *argv[])
{
glob_t gl;
for(int i = ; i < argc; ++i) {
gl.gl_offs = ;
glob(argv[i], GLOB_TILDE, , &gl);
print_gl(&gl);
globfree(&gl);
}
return ;
} static void print_gl(glob_t *gl)
{
for(unsigned int i = ; i < gl->gl_pathc; ++i)
printf("%s/n", gl->gl_pathv[i]);
printf("++++++++++++++++++++++/n");
}
编译:
gcc -std=c99 -g -W -Wall -Wextra -o mytest main.c
执行示例:
./mytest "./*.cpp" "./*.h" "./make*" "~/p*/p?ng"
注意:上诉命令中引号是必需的,否则shell会将模式展开!
实例4:
用glob的递归调用可以找到系统任意路径的所有文件。如下例子:
#include <stdio.h>
#include <glob.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h> static int OpenDir(const char *buf)
{
int ret;
char path[] = {};
char temp[] = {};
char *tp = NULL;
glob_t globbuf;
struct stat fileinfo;
int i;
char *ptr = NULL,*last_ptr = NULL;
strcpy(path,buf);
if(buf[strlen(buf)- ] == '/')
strcat(path,"*");
else
strcat(path,"/*");
if((ret = glob(path,GLOB_NOSORT,NULL,&globbuf)) != ){
if(GLOB_NOMATCH == ret)
return ;
else
return -;
}
strcpy(path,buf);
if(buf[strlen(buf)- ] == '/')
strcat(path,".*");
else
strcat(path,"/.*"); if((ret = glob(path,GLOB_APPEND,NULL,&globbuf)) != ){
if(GLOB_NOMATCH == ret)
return ;
else
return -;
}
for(i = ;i < globbuf.gl_pathc;i++){
ret = lstat(globbuf.gl_pathv[i],&fileinfo);
if(ret != ){
perror("lstat()");
return -;
}
if( == S_ISDIR(fileinfo.st_mode)){
printf("\n%s is directory!\n",globbuf.gl_pathv[i]);
strcpy(temp,globbuf.gl_pathv[i]);
tp = temp;
while((last_ptr = strsep(&tp,"/")) != NULL){
ptr = last_ptr;
}
if((strcmp(ptr,".") == ) || (strcmp(ptr,"..") == ))
continue;
ret = OpenDir(globbuf.gl_pathv[i]);
if(ret != ){
printf("*****opendir() error!\n");
}
}
else
{
printf("%s\n",globbuf.gl_pathv[i]);
}
}
return ;
}
int main(int argc, char *argv[])
{
glob_t globbuf;
int ret ;
struct stat fileinfo;
int i;
if(argc != ){
printf("argument error!\n");
}
ret = OpenDir(argv[]);
if(ret != ){
printf("opendir() error!\n");
return -;
}
return ;
}
执行如下命令获取当前路径中所有文件:
[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% {
...$ S2 n$ 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; _$ H% u4 f7 ^5 A/ F- a$ ~
让我们仔细看文档, 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()/ i$ N! 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。
glob函数的使用的更多相关文章
- php glob()函数实现目录文件遍历与寻找与模式匹配的文件路径
采用PHP函数glob实现寻找与模式匹配的文件路径,主要讨论glob()函数的作用和用法,利用glob函数读取目录比其它的要快N倍,因为glob函数是内置函数处理起来自然要快. 一,函数原型 arra ...
- PHP glob() 函数
定义和用法 glob() 函数返回匹配指定模式的文件名或目录. 该函数返回一个包含有匹配文件 / 目录的数组.如果出错返回 false. 语法 glob(pattern,flags) 参数 描述 fi ...
- PHP glob() 函数用法
glob() 函数返回匹配指定模式的文件名或目录. 该函数返回一个包含有匹配文件 / 目录的数组.如果出错返回 false. 语法 array glob ( string $pattern [, in ...
- 用glob()函数返回目录下的子文件以及子目录
glob() 函数返回匹配指定模式的文件名或目录 相对于readdir()和opendir()来说,使用glob()函数会方便很多 代码1: <?php function getfilename ...
- [python]glob模块中的glob()函数为什么返回空列表??
最近在学习语音的知识,看一个语音合成实现的相关工具包的源代码,碰到了glob()函数.然后开启了我与这个函数相爱想杀的一个下午. 摘自官网解释: https://docs.python.org/2/l ...
- PHP glob() 函数详解
PHP glob() 函数详解 一.总结 glob()作用:glob() 函数返回匹配指定模式的文件名或目录. glob()返回值:该函数返回一个包含有匹配文件 / 目录的数组.如果出错返回 fals ...
- 使用php glob函数查找文件,遍历文件目录(转)
函数说明:array glob ( string $pattern [, int $flags ] )功能:寻找与模式匹配的文件路径,返回包含匹配文件(目录)的数组(注:被检查的文件必须是服务器系统的 ...
- glob函数 循环遍历子目录下的文件
<?php foreach (glob("ueditor\php\upload\image\*\*.png") as $filename) { echo "$fil ...
- php 目录函数和日期函数
continue . break . exit目录函数opendir(); 打开一个文件夹is_file 只判断文件是否存在: file_exists 判断文件是否存在或者是目录是否存在: is_di ...
随机推荐
- SLD 官方实例
基于xml标准的sld格式: <?xml version="1.0" encoding="UTF-8"?> <StyledLayerDescr ...
- javascript sleep方法
function sleep(numberMillis) { var now = new Date(); var exitTime = now.getTime() + numberMi ...
- python discover 函数介绍
discover(start_dir,pattern='test*.py',top_level_dir=None)找到指定目录下所有测试模块,并可递归查到子目录下的测试木块,只有匹配到的文件名才会被加 ...
- csu 1551(线段树+DP)
1551: Longest Increasing Subsequence Again Time Limit: 2 Sec Memory Limit: 256 MBSubmit: 267 Solve ...
- Reverse Nodes in k-Group——简单的指针问题
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...
- 搭建简单的CGI应用程序
原文来源于<核心编程3>第10章web编程 一.静态文件+脚本文件 1.首先开启cgiweb服务器 python2 -m CGIHTTPServer 8000 看到如下反应 2.服务器目录 ...
- s12-day03-work01 python修改haproxy配置文件(初级版本)
#!/usr/local/env python3 ''' Author:@南非波波 Blog:http://www.cnblogs.com/songqingbo/ E-mail:qingbo.song ...
- [实战]MVC5+EF6+MySql企业网盘实战(17)——思考2
写在前面 今天吃饭回来,突然有一个更好的想法,这里做一下记录. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) [实战 ...
- 06易普优APS行业方案:包装印刷行业高级计划排程
易普优APS行业方案:包装印刷行业高级计划排程 一.包装印刷行业发展概况 网络购物催生包装印刷行业迅猛发展,目前已具有万亿市场规模,全国包装印刷企业总数达30万家,其中规模以上企业只有2万多家,已然成 ...
- LoadRunner监控Linux的三种方法
方法一.LR + SiteScope/nmon 方法二.使用rstatd包 1.下载rpc.rstatd-4.0.1.tar.gz 2.解压缩 tar -zxvf rpc.rstatd-4.0.1.t ...