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 ...
随机推荐
- acm专题---动态规划
题目来源:http://hihocoder.com/problemset/problem/1400?sid=983096 #1400 : Composition 时间限制:10000ms 单点时限:1 ...
- int各种数据类型的表示范围
计算方法:1.正数部分数部分:2^(字节数*8-1)-1 2.负数部分:-(2^(字节数*8-1)+1) unsign int:正数部分*2+1
- CSS Sprites的原理(图片整合技术)(CSS精灵)/雪碧图
CSS Sprites的原理(图片整合技术)(CSS精灵)/雪碧图 一.将导航背景图片,按钮背景图片等有规则的合并成一张背景图,即将多张图片合为一张整图,然后用background-positio ...
- C#矩形框沿直线移动
C#中用GDT+的一系列方式,可以绘制各种图形:点,直线,圆形,矩形...... C#中这些图形的绘制,一般教程的demo中给出的代码,是在Form1_Paint(object sender, Pai ...
- IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) E - Bear and Forgotten Tree 2 链表
E - Bear and Forgotten Tree 2 思路:先不考虑1这个点,求有多少个连通块,每个连通块里有多少个点能和1连,这样就能确定1的度数的上下界. 求连通块用链表维护. #inclu ...
- centos6.5 下安装mysql5.7
http://blog.csdn.net/cryhelyxx/article/details/49757217 按步骤一路执行下去. 以下是补充: linux下,在mysql正常运行的情况下,输入my ...
- Educational Codeforces Round 38 部分题解
D. Buy a Ticket 分析 建一个源点,连向所有结点,边的花费为那个结点的花费,图中原有的边花费翻倍,最后跑一遍最短路即可. code #include<bits/stdc++.h&g ...
- Centos 7 mysql 安装使用记
某次把美团云1G 1核 centos 7 装到死机,明白了源码编译安装mysql是个大坑,遂绕路到其他大道. 安装命令 wget http://dev.mysql.com/get/mysql-comm ...
- HDU 2222 Keywords Search 【AC自动机】
题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=2222] 题意:给出很多小字符串,然后给出一个文本串,问文本串中包含多少个小字符串.也就是说如果文本串 ...
- openssl-0.9.8k_WIN32(RSA密钥生成工具
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha openssl-0.9.8k_WIN32(RSA密钥生成工具