initial commit
This commit is contained in:
93
searchword.c
Normal file
93
searchword.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define LINE_BUF_SIZE 8192
|
||||||
|
|
||||||
|
static const char *search_word;
|
||||||
|
static int ignore_case = 0;
|
||||||
|
|
||||||
|
// Проверка вхождения подстроки с учётом регистра
|
||||||
|
char *find_substr(const char *haystack, const char *needle) {
|
||||||
|
if (!ignore_case)
|
||||||
|
return strstr(haystack, needle);
|
||||||
|
// Игнорирование регистра
|
||||||
|
size_t nl = strlen(needle);
|
||||||
|
for (const char *p = haystack; *p; ++p) {
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < nl; ++i) {
|
||||||
|
if (tolower((unsigned char)p[i]) != tolower((unsigned char)needle[i]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == nl)
|
||||||
|
return (char*)p;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void search_file(const char *filepath) {
|
||||||
|
FILE *f = fopen(filepath, "r");
|
||||||
|
if (!f) return; // не удалось открыть — пропустить
|
||||||
|
char line[LINE_BUF_SIZE];
|
||||||
|
unsigned long lineno = 0;
|
||||||
|
while (fgets(line, sizeof(line), f)) {
|
||||||
|
lineno++;
|
||||||
|
if (find_substr(line, search_word)) {
|
||||||
|
printf("%s:%lu: %s", filepath, lineno, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_dir(const char *path) {
|
||||||
|
DIR *d = opendir(path);
|
||||||
|
if (!d) return;
|
||||||
|
struct dirent *entry;
|
||||||
|
while ((entry = readdir(d)) != NULL) {
|
||||||
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
char fullpath[PATH_MAX];
|
||||||
|
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
|
||||||
|
struct stat st;
|
||||||
|
if (stat(fullpath, &st) == -1) continue;
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
process_dir(fullpath);
|
||||||
|
} else if (S_ISREG(st.st_mode)) {
|
||||||
|
search_file(fullpath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char *dir = NULL;
|
||||||
|
int argi = 1;
|
||||||
|
if (argc > 1 && strcmp(argv[1], "-i") == 0) {
|
||||||
|
ignore_case = 1;
|
||||||
|
argi++;
|
||||||
|
}
|
||||||
|
if (argi < argc)
|
||||||
|
dir = argv[argi++];
|
||||||
|
else {
|
||||||
|
const char *home = getenv("HOME");
|
||||||
|
if (!home) {
|
||||||
|
fprintf(stderr, "Не задана директория и переменная HOME не установлена.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
static char default_dir[PATH_MAX];
|
||||||
|
snprintf(default_dir, sizeof(default_dir), "%s/", home);
|
||||||
|
dir = default_dir;
|
||||||
|
}
|
||||||
|
if (argi < argc)
|
||||||
|
search_word = argv[argi];
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Использование: %s [-i] [директория] слово\n", argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
process_dir(dir);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user