Сливал это на соседним форуме, решил скинуть и сюда. Буд рад любому мнению, если с оформлением беда, прошу простить)
"Сделал" свой скрипт c ПОМОЩЬЮ АИ (ВЕСЬ КОД ПИСАЛ АИ), оптимизированный для слабых систем | ЯП rust
для меня подходит, быстрый и умеет работать со многим txt файлами, закинул текстовики в папку и ищешь себе по ключевым словам = сказка
Для начала нам потребуется две папки, одна - где будут лежать txt файл со строками, вторая - для сохранения результата ( результат сохраняется в виде Result_site.txt )
Собственно как работает скрипт
Первый запуск
Берете код, скомпилируйте и софт готов
Для новичков да и для старичков наверное пойдет
Берите / пробуйте, говорите какое АИ говно, это никому не нужный мусор, критикуйте и предлагайте
"Сделал" свой скрипт c ПОМОЩЬЮ АИ (ВЕСЬ КОД ПИСАЛ АИ), оптимизированный для слабых систем | ЯП rust
для меня подходит, быстрый и умеет работать со многим txt файлами, закинул текстовики в папку и ищешь себе по ключевым словам = сказка
Для начала нам потребуется две папки, одна - где будут лежать txt файл со строками, вторая - для сохранения результата ( результат сохраняется в виде Result_site.txt )
Собственно как работает скрипт
Первый запуск
- указываешь путь где лежат txt файлы ( C:\WW\WW\ULP )
- указываешь путь сохранения результата ( C:\WW\WW\RESULT )
- вбиваешь запрос вида Admin, admin, .com, site.com ( берет все не учитывая регистр)
Берете код, скомпилируйте и софт готов
Для новичков да и для старичков наверное пойдетБерите / пробуйте, говорите какое АИ говно, это никому не нужный мусор, критикуйте и предлагайте
У вас должно быть более 10 сообщений для просмотра скрытого контента.
Код:
[package]
name = "search_app"
version = "0.1.0"
edition = "2021"
[dependencies]
eframe = "0.27.2"
rfd = "0.14.1
"
У вас должно быть более 10 сообщений для просмотра скрытого контента.
Код:
use std::fs::File;
use std:🇮🇴:{self, BufReader, Read, Write};
use std::path::Path;
use std::sync::mpsc;
use std::thread;
use std::time::Instant;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Default, Clone)]
struct Config {
folder_path: String,
output_path: String,
}
fn load_config() -> Config {
if Path::new("config.json").exists() {
match std::fs::read_to_string("config.json") {
Ok(content) => serde_json::from_str(&content).unwrap_or_else(|e| {
eprintln!("Failed to parse config.json: {}. Using default config.", e);
Config::default()
}),
Err(e) => {
eprintln!("Failed to read config.json: {}. Using default config.", e);
Config::default()
}
}
} else {
Config::default()
}
}
fn save_config(config: &Config) {
let config_json = serde_json::to_string_pretty(config).expect("Failed to serialize config");
std::fs::write("config.json", config_json).expect("Failed to write config file");
}
fn process_file(file_path: &str, keyword: &str) -> io::Result<Vec<String>> {
let file = File::open(file_path)?;
let mut reader = BufReader::new(file);
let mut results = Vec::new();
let mut buffer = Vec::new();
let chunk_size = 16 * 1024 * 1024; // 16 MB
let keyword_lower = keyword.to_lowercase();
loop {
buffer.clear();
let bytes_read = reader
.by_ref()
.take(chunk_size)
.read_to_end(&mut buffer)?;
if bytes_read == 0 {
break;
}
let chunk = String::from_utf8_lossy(&buffer);
let lines = chunk.split('\n');
for line in lines {
if !line.is_empty() && line.to_lowercase().contains(&keyword_lower) {
results.push(line.to_string());
}
}
}
Ok(results)
}
fn search_files(folder_path: &str, output_path: &str, keyword: &str) -> io::Result<()> {
let start_time = Instant::now();
println!("Начинаю поиск '{}' в папке {}...", keyword, folder_path);
let files: Vec<_> = std::fs::read_dir(folder_path)?
.filter_map(|entry| {
let path = entry.ok()?.path();
if path.extension().map(|ext| ext == "txt").unwrap_or(false) {
Some(path.to_str()?.to_string())
} else {
None
}
})
.collect();
if files.is_empty() {
println!("Ошибка: TXT-файлы не найдены в папке!");
return Ok(());
}
let total_files = files.len();
println!("Найдено {} файлов для обработки...", total_files);
let (tx, rx) = mpsc::channel();
let keyword_owned = keyword.to_string();
let output_path_owned = output_path.to_string();
thread::spawn(move || {
let mut processed_files = 0;
let mut result_list = Vec::new();
for file in files {
if let Ok(results) = process_file(&file, &keyword_owned) {
result_list.extend(results);
}
processed_files += 1;
tx.send((processed_files, total_files, false)).unwrap();
}
// Заменяем недопустимые символы в имени файла
let safe_keyword = keyword_owned.replace(|c: char| !c.is_alphanumeric() && c != '_', "_");
let result_file = format!("{}\\Result_{}.txt", output_path_owned, safe_keyword);
match std::fs::create_dir_all(&output_path_owned) {
Ok(_) => match std::fs::write(&result_file, result_list.join("\n")) {
Ok(_) => println!("Результат сохранен в {}", result_file),
Err(e) => println!("Ошибка записи файла {}: {}", result_file, e),
},
Err(e) => println!("Ошибка создания папки {}: {}", output_path_owned, e),
}
let end_time = Instant::now();
let duration = end_time - start_time;
tx.send((result_list.len(), duration.as_secs() as usize, true)).unwrap();
});
while let Ok((value1, value2, done)) = rx.recv() {
if done {
println!(
"Поиск завершен! Найдено: {}. Время: {} сек",
value1, value2
);
} else {
println!("Обработка: {}/{} файлов", value1, value2);
}
}
Ok(())
}
fn main() -> io::Result<()> {
println!("Консольная утилита для поиска по TXT-файлам (Rust)");
println!("Для выхода введите 'exit'");
let mut config = load_config();
// Показать текущие пути, если они есть
println!(
"Текущая папка с TXT-файлами: {}",
if config.folder_path.is_empty() {
"Не указана"
} else {
&config.folder_path
}
);
println!(
"Текущая папка для результатов: {}",
if config.output_path.is_empty() {
"Не указана"
} else {
&config.output_path
}
);
print!("Хотите указать новые пути? (y/n): ");
io::stdout().flush()?;
let mut answer = String::new();
io::stdin().read_line(&mut answer)?;
let specify_paths = answer.trim().to_lowercase() == "y";
if specify_paths || config.folder_path.is_empty() || config.output_path.is_empty() {
println!("Введите путь к папке с TXT-файлами (например, C:\\TextFiles):");
let mut folder_path = String::new();
io::stdin().read_line(&mut folder_path)?;
config.folder_path = folder_path.trim().to_string();
println!("Введите путь к папке для сохранения результатов (например, C:\\Results):");
let mut output_path = String::new();
io::stdin().read_line(&mut output_path)?;
config.output_path = output_path.trim().to_string();
save_config(&config);
}
loop {
if !Path::new(&config.folder_path).is_dir() {
println!("Ошибка: Указанная папка {} не существует!", config.folder_path);
println!("Введите новый путь к папке с TXT-файлами (например, C:\\TextFiles):");
let mut folder_path = String::new();
io::stdin().read_line(&mut folder_path)?;
config.folder_path = folder_path.trim().to_string();
save_config(&config);
continue;
}
println!("Введите ключевое слово для поиска (например, site, site/, .com):");
let mut keyword = String::new();
io::stdin().read_line(&mut keyword)?;
let keyword = keyword.trim();
if keyword.to_lowercase() == "exit" {
println!("Выход из программы.");
break;
}
if keyword.is_empty() {
println!("Ошибка: Введите ключевое слово!");
continue;
}
search_files(&config.folder_path, &config.output_path, keyword)?;
println!("Готово! Введите новое ключевое слово или 'exit' для выхода.");
}
Ok(())
}