我想编写一个 Ruby 脚本 (repl.rb),它可以将二进制文件中的字符串(字符串由正则表达式定义)替换为不同但长度相同的字符串。 它像过滤器一样工作,输出到 STDOUT,可以重定向(ruby repl.rb data.bin > data2.bin),正则表达式和替换可以硬编码。我的做法是:
#!/usr/bin/ruby
fn = ARGV[0]
regex = /\-\-[0-9a-z]{32,32}\-\-/
replacement = "--0ca2765b4fd186d6fc7c0ce385f0e9d9--"
blk_size = 1024
File.open(fn, "rb") {|f|
while not f.eof?
data = f.read(blk_size)
data.gsub!(regex, str)
print data
end
}
我的问题是,当字符串以这种方式定位在文件中时,它会干扰读取二进制文件所使用的 block 大小。例如,当 blk_size=1024 并且我第一次出现该字符串时,它从字节位置 1000 开始,所以我不会在“数据”变量中找到它。下一个读取周期也会发生同样的情况。我应该使用不同的 block 大小对整个文件进行两次处理,以确保避免这种有值(value)的情况,还是有任何其他方法?
最佳答案
我认为像 sed 这样的工具可能是更好的选择。也就是说,这里有一个想法:读取 block 1 和 block 2 并将它们连接成一个字符串,然后对组合的字符串执行替换。再次将它们分开并打印 block 1。然后读取 block 3 并加入 block 2 和 3 并执行上述替换。再次拆分它们并打印 block 2。重复直到文件末尾。我还没有测试过它,但它应该看起来像这样:
File.open(fn, "rb") do |f|
last_block, this_block = nil
while not f.eof?
last_block, this_block = this_block, f.read(blk_size)
data = "#{last_block}#{this_block}".gsub(regex, str)
last_block, this_block = data.slice!(0, blk_size), data
print last_block
end
print this_block
end
以这种方式进行操作可能会产生不小的性能损失,但根据您的用例,这是可以接受的。
关于可以将二进制文件中的字符串替换为不同但长度相同的字符串的 Ruby 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33991306/