• linux c 文件内容搜索小工具


    经常需要在项目中搜索指定字符串,又不想打开ide,于是自己谢了个简单的搜索工具:搜索指定目录下所有包含指定字符串的文件。

    很简单:扫描指定目录下的所有文件,依次以文本方式打开所有文件,逐行读取内容进行搜索;如果包含要搜索的字符串,就输出。

    在输出的时候,使用ascii码对匹配的搜索串做了高亮显示。


    代码如下:

    View Code
      1 #include <stdio.h>
      2 #include <dirent.h>
      3 #include <string.h>
      4 #include <errno.h>
      5 
      6 #define _DEBUG
      7 
      8 #define USAGE printf("usage:\e[1mxsearch\e[0m \e[4mDIRECTORY\e[0m \e[4mKEYWORDS\e[0m\n"); return -1;
      9 
     10 static char szBase[512= {0};
     11 static char szKey[512= {0};
     12 
     13 int search_inline(char* file, char* line, int nline)
     14 {
     15     int ret = -1;
     16     
     17     char* p = strstr(line, szKey);
     18     if(p == NULL)
     19     {
     20         return ret;
     21     }
     22     //printf("\e[34m[%s-%d]\e[0m%s", file, nline+1, line);
     23     printf("\e[34m\e[1m[%s-%d]\e[0m", file, nline+1);
     24     
     25     char* pTemp = line;
     26     char* pTail = (p + strlen(szKey));
     27     while(p)
     28     {
     29         while(pTemp != p)
     30         {
     31             printf("%c"*pTemp);
     32             pTemp ++;
     33         }
     34         printf("\e[31m\e[1m%s\e[0m", szKey);
     35         
     36         p += strlen(szKey);
     37         pTail = pTemp = p;
     38 
     39         p = strstr(p, szKey);
     40     }
     41     printf(pTail);
     42 
     43     return ret;
     44 }
     45 
     46 int search_infile(char* szfile)
     47 {
     48     int ret = -1;
     49     
     50     FILE*    file = fopen(szfile, "r");
     51     char*     line = NULL;
     52 
     53     if(file != NULL)
     54     {
     55         int n = 0;
     56         size_t size;
     57         while(getline(&line, &size, file) != -1)
     58         {
     59             search_inline(szfile, line, n);
     60             n++;
     61         }
     62 
     63         free(line);
     64         fclose(file);
     65     }
     66 #ifdef _DEBUG
     67     else
     68     {
     69         printf("open file \'%s\' failed!%s\n", szfile, strerror(errno));
     70     }
     71 #endif
     72     return ret;
     73 }
     74 
     75 int search_indir(char* dir)
     76 {
     77     struct dirent** namelist;
     78     int n = scandir(dir, &namelist, 00);
     79     if(n < 0)
     80     {
     81         perror("error in scandir\n");
     82         return -1;
     83     }
     84     
     85     while(n--)
     86     {
     87         if(strcmp(".", namelist[n]->d_name)== 0
     88         ||strcmp("..", namelist[n]->d_name) == 0)
     89         {
     90             //printf("ignored!%s\n", namelist[n]->d_name);
     91             continue;
     92         }
     93 
     94         char szTemp[512= {0};
     95         sprintf(szTemp, "%s/%s", dir, namelist[n]->d_name);
     96         //printf("searching:%s\n", szTemp);        
     97 
     98         if(namelist[n]->d_type == DT_REG)
     99         {
    100             search_infile(szTemp);
    101         }
    102         else if(namelist[n]->d_type == DT_DIR)
    103         {
    104             search_indir(szTemp);
    105         }
    106         free(namelist[n]);
    107     }
    108     free(namelist);
    109 }
    110 
    111 int main(int argc, void** argv)
    112 {
    113     if(argc < 3)
    114     {
    115         USAGE;
    116     }
    117 
    118     strcpy(szBase, argv[1]);
    119     
    120     //keyworks fromat: -'KEY WORDS', will search KEY WORDS
    121     if((strncmp(argv[2], "\'"2== 0&& (strlen(argv[2]) > 3))
    122     {
    123         char* p = argv[2+ 2;
    124         strncpy(szKey, p, strlen(p)-1);
    125         printf("searching:%s\n", szKey);
    126     }
    127     else
    128     {
    129         strcpy(szKey, argv[2]);
    130     }
    131 
    132     search_indir(szBase);
    133         
    134     return 0;
    135 }

    示例:





    update:

    增加选项:

    -i 排除指定文件(文件夹)

    -type 只搜索指定类型(后缀)的文件

    均支持','分隔

    #include <stdio.h>
    #include <dirent.h>
    #include <string.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <iostream>
    #define _DEBUG
    
    #define USAGE printf("usage:\e[1mxsearch\e[0m \e[4mDIRECTORY\e[0m \e[4mKEYWORDS\e[0m \e[4m-i IGNORE\e[0m\n"); return -1;
    
    static char szBase[512] = {0};
    static char szKey[512] = {0};
    
    char** g_ignore_list = NULL;
    int g_ignore_list_size = 0;
    
    char** g_file_type_list = NULL;
    int g_file_type_list_size = 0;
    
    int search_inline(char* file, char* line, int nline)
    {
        int ret = -1;
        
        char* p = strstr(line, szKey);
        if(p == NULL)
        {
            return ret;
        }
        //printf("\e[34m[%s-%d]\e[0m%s", file, nline+1, line);
        printf("\e[34m\e[1m[%s:%d]\e[0m", file, nline+1);
        
        char* pTemp = line;
        char* pTail = (p + strlen(szKey));
        while(p)
        {
            while(pTemp != p)
            {
                printf("%c", *pTemp);
                pTemp ++;
            }
            printf("\e[31m\e[1m%s\e[0m", szKey);
            
            p += strlen(szKey);
            pTail = pTemp = p;
    
            p = strstr(p, szKey);
        }
    	//TODO if pTail contains some format string, such as ", \ %u, %d, might got SIGSEGV
        //printf(pTail);
    	std::cout<<pTail;
        return ret;
    }
    
    bool check_file_type(const char* name)
    {
    	if(g_file_type_list_size == 0)
    	{
    		return true;
    	}
    	
    	//get file type
    	size_t _len = strlen(name);
    	if(_len == 0)
    	{
    		return false;
    	}
    
    	const char* _p = name + _len - 1;
    	while(_p != name)
    	{
    		if(*_p == '.')
    		{
    			break;
    		}
    		_p--;
    	}	
    	_p++;
    	//printf("type:%s\n", _p);
    
            int i=0;
            for(;i<g_file_type_list_size; i++)
            {
                    if(g_file_type_list[i] && strcmp(g_file_type_list[i], _p) == 0)
                    {
                            return true;
                    }
            }
    	
    
    	return false;
    }
    
    bool check_ignore(const char* name)
    {
    	if(name == NULL)
    	{
    		return false;
    	}
    
    	int i=0;
    	for(;i<g_ignore_list_size; i++)
    	{
    	        if(g_ignore_list[i] && strcmp(g_ignore_list[i], name) == 0)
    		{
    			return false;
    		}
    	}
    
    	return true;
    }
    
    int search_infile(char* szfile)
    {
    	//printf("file:%s\n", szfile);
            if(check_file_type(szfile) == false)
            {
    		//printf("XXXXXXXXXufcked.\n");
                    return 0;
            }
    
        int ret = -1;
    
        FILE*    file = fopen(szfile, "r");
        char*     line = NULL;
    
        if(file != NULL)
        {
            int n = 0;
            size_t size;
            while(getline(&line, &size, file) != -1)
            {
                search_inline(szfile, line, n);
                n++;
            }
    
            free(line);
            fclose(file);
        }
    #ifdef _DEBUG
        else
        {
            printf("open file \'%s\' failed!%s\n", szfile, strerror(errno));
        }
    #endif
        return ret;
    }
    
    int search_indir(char* dir)
    {
        struct dirent** namelist;
        int n = scandir(dir, &namelist, 0, 0);
        if(n < 0)
        {
            perror("error in scandir\n");
            return -1;
        }
        
        while(n--)
        {
            if(strcmp(".", namelist[n]->d_name)== 0
            ||strcmp("..", namelist[n]->d_name) == 0)
            {
                //printf("ignored!%s\n", namelist[n]->d_name);
                continue;
            }
    
    	if(check_ignore(namelist[n]->d_name) == false)
    	{
    		continue;
    	}
    
            char szTemp[512] = {0};
            sprintf(szTemp, "%s/%s", dir, namelist[n]->d_name);
            //printf("searching:%s\n", szTemp);        
    
            if(namelist[n]->d_type == DT_REG)
            {
                search_infile(szTemp);
            }
            else if(namelist[n]->d_type == DT_DIR)
            {
                search_indir(szTemp);
            }
            free(namelist[n]);
        }
        free(namelist);
    }
    
    char** split_param_list(const char* param, const char* delim, int* size)
    {
    	if(param == NULL || delim == NULL || size == NULL)
    	{
    		return NULL;
    	}
    	//printf("%s\n", param);
    
    	char** list = NULL;
    	int _len = strlen(param);
    	*size = 0;
    
    	int i=0;
    	for(; i<_len; i++)
    	{
    		if(param[i] == *delim)
    		{
    			(*size)++;
    		}
    	}	
    	(*size)++;
    
    	list = (char**)malloc(*size);
    
    	int _count = 0;
    	const char* _start=param;
    	for(i=0; i<_len; i++)
    	{
    		if(param[i] == *delim)
    		{
    			const char* _p = param + i;
    			if(_p-_start == 0)
    			{
    				_start++;
    				continue;
    			}
    
    			list[_count] = (char*)malloc(_p-_start);
    			strncpy(list[_count], _start, _p-_start);
    			
    			_start = ++_p;
    			_count++;
    		}
    	}
    	
    	if(*_start != *delim)
    	{
    		const char* _p = param + i;
                    list[_count] = (char*)malloc(_p-_start);
                    strncpy(list[_count], _start, _p-_start);
    	}
    
    	//dump
    	/*for(i=0; i<*size; i++)
    	{
    		printf("%s\n", list[i]);
    	}
    	*/
    	return list;
    }
    
    void test()
    {
    	split_param_list("sdvs,gdfa,cd,a232,fuck",",", &g_ignore_list_size);
    	exit(0);
    }
    
    int main(int argc, char** argv)
    {
    	//test();
    
        if(argc < 3)
        {
            USAGE;
        }
    
        strcpy(szBase, argv[1]);
        
        //keyworks fromat: -'KEY WORDS', will search KEY WORDS
        if((strncmp(argv[2], "\'", 2) == 0) && (strlen(argv[2]) > 3))
        {
            char* p = argv[2] + 2;
            strncpy(szKey, p, strlen(p)-1);
            printf("searching:%s\n", szKey);
        }
        else
        {
            strcpy(szKey, argv[2]);
        }
    
    	
    	if(argc > 3)
    	{
    		for(int i=3; i<argc; i++)
    		{
    			if(strcmp("-i", argv[i]) == 0)
    			{
    				if(i == argc -1)
    				{
    					USAGE;
    				}
    				g_ignore_list =	split_param_list(argv[++i], ",", &g_ignore_list_size);
    			}
    			else if(strcmp("-type", argv[i]) == 0)
    			{                           
    				if(i == argc -1)
                                    {
                                            USAGE;
                                    }
    				g_file_type_list = split_param_list(argv[++i], ",", &g_file_type_list_size);
    				
    			}
    		}
    	}
    
    	printf("************************************************\n");
    	if(g_file_type_list_size > 0)
    	{
    		printf("\n[file type]:\n");
    		int i=0;
    		for (;i<g_file_type_list_size; i++)	
    		{
    			printf("%s\n", g_file_type_list[i]);
    		}
    	}
    
            if(g_ignore_list_size > 0)
            {
                    printf("\n[ignore]:\n");
                    int i=0;
                    for (;i<g_ignore_list_size; i++)
                    {
                            printf("%s\n",g_ignore_list[i]);
                    }
            }
    	printf("************************************************\n");
    
        search_indir(szBase);
            
        return 0;
    }
    

      


  • 相关阅读:
    3.29Java流程控制语句之循环结构
    3.27Java自动类型转化
    3.27Java流程控制语句
    3.27字符串连接符
    计算机系统概论
    《算法导论》第12章 二叉查找树 (2)查找、插入与删除
    《算法导论》第14章 数据结构的扩张 (1)动态顺序统计
    《算法导论》第12章 二叉查找树 (3)基数树
    关于算法学习的总结和感悟(原创)
    《Windows游戏编程大师技巧》二、Windows编程模型
  • 原文地址:https://www.cnblogs.com/chutianyao/p/2039043.html
Copyright © 2020-2023  润新知