Linux中glob函数解析

函数原型:

int glob(const char *pattern, int flags,
                           int errfunc(const char *epath, int eerrno),
                           glob_t *pglob);

pglob的类型glob_t
typedef struct {
    size_t    gl_pathc;    //匹配到的数量
    char    **gl_pathv;    //匹配到的元素放在这里
    size_t    gl_offs; 
}glob_t;


参数:

    pattern      要分析的路径,如/*表示匹配根文件下的所有文件(不包括隐藏文件)   

    flags        flags参数可以设置特殊要求,如无特殊要求置为0

    errfunc      glob函数执行出错会执行的函数,出错的路径会回填到epath中,

                 出错的原因回填到eerrno中。如不关注错误可设置为NULL

    pglob        解析出来的结果放在这个参数里

返回值:

    成功 0

示例

示例1:

使用glob函数打印/etc/ 目录下以a开头.conf结尾的文件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glob.h>
#include <unistd.h>


#define PAT    "/etc/a*.conf"


static int errfunc(const char *errpath,int eerrno)
{
    puts(errpath);
    fprintf(stderr,"ERROR MSG:%s\n",strerror(eerrno));
    return 0;
}



int main()
{
    
    glob_t globres;
    int i,err;

    err = glob(PAT,0,errfunc,&globres);
    if(err)
    {
        printf("Error code = %d\n",err);
        exit(1);   
    }
    //打印解析出来的参数
    for(i = 0;i < globres.gl_pathc;i++)
    {
        puts(globres.gl_pathv[i]);
        
    }


    //释放申请的空间
    globfree(&globres);

    return 0;
}

运行结果如下图:

示例2:

使用glob函数实现du命令,查看文件或目录的大小。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <glob.h>


#define	PATHSIZE	1024	

static int path_noloop(const char *path)
{
	char* pos;
    //使用strrchr找到字符串里最右边的一个字符即 / ,成功pos指向 / 所在的地址
    pos = strrchr(path,'/');
    if(pos == NULL)
        exit(1);
    if(strcmp(pos+1,".")==0 || strcmp(pos+1,"..") == 0)
        return 0;
    
    return 1;
}

static int64_t mydu(const char *path)
{
    struct stat statres;
    char nextpath[PATHSIZE];
    glob_t globres;
    int err,i;
    int64_t sum;
    
    //使用lstat函数获得文件(目录)属性,lstat函数不会对链接文件展开
    if(lstat(path,&statres) < 0)
    {
        perror("lstat()");
        exit(1);
    }
    //判断获得的属性信息,使用宏判断是否是目录,如果是非目录直接返回大小
    if(!S_ISDIR(statres.st_mode))
    	return statres.st_blocks;
    //将path的内容拷贝到nextpath中
    strncpy(nextpath,path,PATHSIZE);

    //在nextpath中追加/*字符串
    strncat(nextpath,"/*",PATHSIZE);
    //使用glob函数解析nextpath中非隐藏的文件
    err = glob(nextpath,0,NULL,&globres);
    if(err)
    {
        printf("glob error code = %d\n",err);
        exit(1);
    }
    
    
    
    //将path的内容拷贝到nextpath中
    strncpy(nextpath,path,PATHSIZE);
    //在nextpath中追加/.*字符串
    strncat(nextpath,"/.*",PATHSIZE);
    //使用glob函数解析nextpath中隐藏的文件,GLOB_APPEND标志意思是将结果追加到 pglob 结构体中
    err = glob(nextpath,GLOB_APPEND,NULL,&globres);
    if(err)
    {
        fprintf(stderr,"i ggError code = %s\n",strerror(err));
        exit(1);        
    }
    sum = 0;

    for(i = 0;i < globres.gl_pathc;i++)
	{
		if(path_noloop(globres.gl_pathv[i]))
        	sum+=mydu(globres.gl_pathv[i]);
	}
    //加上本身目录文件的大小
    sum += statres.st_blocks;
    
    globfree(&globres);
    return sum;
    
}


int main(int argc,char **argv)
{
    if(argc < 2)
    {
        fprintf(stderr,"Usage ...\n");
        exit(1);
    }

    printf("%ld\n",mydu(argv[1])/2);
	return 0;
}

运行结果如下:

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值