您的位置:首页 > 运维架构 > Linux

linux c 文件内容搜索小工具

2011-05-06 15:59 429 查看
经常需要在项目中搜索指定字符串,又不想打开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, 0, 0);
79 if(n < 0)
80 {
81 perror("error in scandir\n");
82 return -1;
83 }
84
85 while(n--)
86 {
87 if(strcmp(".", namelist
->d_name)== 0
88 ||strcmp("..", namelist
->d_name) == 0)
89 {
90 //printf("ignored!%s\n", namelist
->d_name);
91 continue;
92 }
93
94 char szTemp[512] = {0};
95 sprintf(szTemp, "%s/%s", dir, namelist
->d_name);
96 //printf("searching:%s\n", szTemp);
97
98 if(namelist
->d_type == DT_REG)
99 {
search_infile(szTemp);
}
else if(namelist
->d_type == DT_DIR)
{
search_indir(szTemp);
}
free(namelist
);
}
free(namelist);
}

int main(int argc, void** argv)
{
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]);
}

search_indir(szBase);

return 0;
}

示例:



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
->d_name)== 0
||strcmp("..", namelist
->d_name) == 0)
{
//printf("ignored!%s\n", namelist
->d_name);
continue;
}

if(check_ignore(namelist
->d_name) == false)
{
continue;
}

char szTemp[512] = {0};
sprintf(szTemp, "%s/%s", dir, namelist
->d_name);
//printf("searching:%s\n", szTemp);

if(namelist
->d_type == DT_REG)
{
search_infile(szTemp);
}
else if(namelist
->d_type == DT_DIR)
{
search_indir(szTemp);
}
free(namelist
);
}
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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: