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 ...
随机推荐
- Vue.js——60分钟快速入门(转)
var vm = new Vue({ el: '#app', data: { people: [{ name: 'Jack', age: 30, sex: 'Male' }, { name: 'Bil ...
- #include<stdarg.h> 可变参数使用
今天上计算方法这课时觉得无聊至极,于是拿出C++编程之道来看了看..无意之中看到了#include<stdarg.h> va_list,va_start,va_end等东西,不知是怎么用的 ...
- hdu 5920(模拟)
Ugly Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- 双系统卸载linux和装双系统的方法
卸载linux系统: 因为本人装的是windows和Ubuntu,所以引导程序在linux系统里,linux系统可以引导windows系统,而Windows不能引导linux,所以需要修改引导程序,使 ...
- javascript练习(二)
案例 输出100个数字 案例 打印100以内 7的倍数 案例 打印100以内的奇数 案例 打印100以内所有偶数的和 打印图形 ********** ********** ********** ...
- Windows实现内网IPMI端口转发
https://www.cnblogs.com/yunweis/p/8024346.html
- markdown 测试代码
这是 H1 这是 H2 这是 H3 这是 H4 这是 H5 这是 H6 A First Level Header A Second Level Header Now is the time for a ...
- Domato学习
A DOM fuzzer 转:https://github.com/google/domato Written and maintained by Ivan Fratric, ifratric@goo ...
- 【拓扑排序或差分约束】Guess UVALive - 4255
题目链接:https://cn.vjudge.net/contest/209473#problem/B 题目大意:对于n个数字,给出sum[j]-sum[i](sum表示前缀和)的符号(正负零),求一 ...
- mySQL 的 2个分类
1.将如下表中的每门成绩都大于80分的人名? 张三 语文 81 张三 数学 75 李四 语文 76 李四 数学 90 王五 语文 81 王五 数学 100 王五 英语 90 select * from ...