经常需要在项目中搜索指定字符串,又不想打开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[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 }
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[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; }