我刚刚使用 y-cruncher 计算完 1110 亿位 PI 数字,并有 104GB 文件。
我遇到了问题。
我想玩一玩,尝试在那里搜索名称、值、标题等,这是一定的数字序列。 然而,像 grep fgrep 和其他搜索一样,即使内存不足,也会崩溃。
整个数字位于 txt 文件中的一行中。
那么,我现在如何找到那里的文本,无论需要多长时间,最好不要将其分割成小文件或类似的文件,以便文件保持不变。
以及将来如何快速搜索那里,例如创建一个搜索站点并已经在那里使用sql/分区到文件中,或者其他东西,在这里建议一些可以帮助的东西。
提前感谢,我尝试了我所说的 grep、fgrepX 和其他一些开源东西。
grep
在搜索其中的文本之前将整个文件读入内存。您可以改为使用 GNU awk 进行多字符 RS 并告诉它一次达到 1000
或任何您喜欢的字符数:
gawk -v RS='.{0,1000}' '/regexp/' file
但是您需要考虑匹配的字符串可能会跨越 1000 个字符的边界,因此请确保每个记录足够大以容纳匹配的字符串,并且您测试连接的 2 个记录,例如:
gawk -v RS='.{0,1000}' (prev $0) ~ /regexp/; {prev=$0}' file
上面的内容显然未经测试,因为问题中没有样本输入/输出供我们测试,并且OP没有告诉我们如果/当正则表达式匹配时他们想要输出什么,等等,所以这一切都留给他们了也想弄清楚。
如果标准程序不够好,请制作自己的程序。
我用 Rust 为你写了这个。我选择 Rust 是因为它有一个令人印象深刻的 memchr::memmem 库。它应该相当快。它绝对不会耗尽内存。我希望它没有任何错误。在线搜索如何安装 Rust。使用
cargo build --release
编译程序。
fastgrep/src/main.rs:
use std::io::Read;
use std::os::unix::ffi::OsStrExt;
fn main() -> std::io::Result<()> {
const BUF_SIZE: usize = 8192;
let args: Vec<_> = std::env::args_os().collect();
let needle: &[u8] = args[1].as_bytes();
let filename = &args[2];
let finder = memchr::memmem::Finder::new(needle);
let mut file = std::fs::File::open(filename)?;
let mut offset = 0;
let mut buffer: Vec<u8> = vec!();
loop {
let old_len = buffer.len();
buffer.resize(old_len + BUF_SIZE, 0);
let bytes_read = file.read(&mut buffer[old_len..])?;
buffer.truncate(old_len + bytes_read);
// eprintln!("old_len {old_len} bytes_read {bytes_read}");
for offset_in_buffer in finder.find_iter(&buffer) {
println!("{}", offset + offset_in_buffer);
}
if bytes_read == 0 {
break;
}
let advance = buffer.len().saturating_sub(needle.len() - 1);
// eprintln!("advance {advance}");
offset += advance;
buffer = buffer[advance..].to_vec();
}
Ok(())
}
fastgrep/Cargo.toml:
[package]
name = "fastgrep"
version = "0.1.0"
edition = "2021"
[dependencies]
memchr = "2.6.4"
Rust 游乐场示例(硬编码参数):
https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=e2385dbb56bdaee15ba4b827245a19e9
祝你好运!请写评论告诉我它是否有效!
如果标准程序不够好,请尝试用于搜索二进制文件的程序。
您的文件并不是真正的二进制文件,其中一些程序可能希望您以十六进制写入针,但至少它们不会尝试逐行读取输入。
这篇文章https://www.baeldung.com/linux/binary-files-pattern-search提到了这些工具:
某些 Linux 发行版提供了其中一些工具的软件包。