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;
}

  

 

 


posted @ 2011-05-06 15:59    阅读(1724)  评论(3编辑  收藏  举报