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 ...
随机推荐
- 后门技术和Linux LKM Rootkit详解
2010-01-15 10:32 chinaitlab chinaitlab 字号:T | T 在这篇文章里, 我们将看到各种不同的后门技术,特别是 Linux的可装载内核模块(LKM). 我们将会发 ...
- request机制
每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前后端的交互 基于HTML + Flask 写一 ...
- Jmeter----连接mysql数据库及常见问题处理
jmeter要链接mysql数据库,首先得下载mysql jdbc驱动包,(注:驱动包的版本一定要与你数据库的版本匹配,驱动版本低于mysql版本有可能会导致连接失败报错) 本人的数据为5.7.18, ...
- 再读《Parallel Programming with Python》并作笔记
并发编程,在哪个语言里都属于高端应用,一定得会了才好意思说懂了这门语言. 在工作中用得并不是很多,忘了一些内容,就慢慢看,慢慢补上. 今天一天看了近三分之一(我看外文越来越快了??:)), 实践一下多 ...
- fastdfs5.11+centos7.2 按照部署(三)【转载】
1.测试 前面两篇博文已对FastDFS的安装和配置,做了比较详细的讲解.FastDFS的基础模块都搭好了,现在开始测试下载. 1.1 配置客户端 同样的,需要修改客户端的配置文件: vim /etc ...
- 今日头条、Face++开发岗面经
今日头条.Face++开发岗面经 [头条] 两个栈实现一个队列.怎么优化 数组每一个元素找出数组右边第一个大于自己的数 实现LRU TCP四次握手 滑动窗口.窗口大小 线程与进程区别 什么是线程安全 ...
- 微信小程序开发之路之组件化
类似于页面,自定义组件拥有自己的 wxml 模版和 wxss 样式. 官方链接 组件化,反过来理解,写重复的页面,方法,写第二遍就烦了,抽取出来就是组件化,可以理解为公用的方法 对于通用的数据,最先想 ...
- HTML中的ul, ol,li , dl,dt, dd标签
ul: unordered lists ol: ordered lists li: Lists ol 有序列表. <ol><li>……</li><li> ...
- 磁盘镜像分析工具Autopsy
磁盘镜像分析工具Autopsy Autopsy是Kali Linux预安装的一款磁盘镜像分析工具.该工具可以对磁盘镜像的卷和文件系统进行分析,支持Unix和Windows系统.Autopsy是一个 ...
- centos7 更改时区
Linux 系统(我特指发行版, 没说内核) 下大部分软件的风格就是不会仔细去考虑向后 的兼容性, 比如你上个版本能用这种程序配置, 没准到了下一个版本, 该程序已经不见了. 比如 sysvinit ...