可以将二进制文件中的字符串替换为不同但长度相同的字符串的 Ruby 脚本?

标签 ruby regex string replace binary

我想编写一个 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/

相关文章:

ruby - 拒绝将信息存储在文件中

ruby-on-rails - Rails, Controller 中的字母数字验证

c++ - 正则表达式查找所有用位字段定义的结构

java - SimpleDateFormat - 您需要使用 RegEx 吗?

python - 查找包含特定值的字符串

html - 为什么 Rails 不显示我的 API 调用结果?

java - 是否有类似 ZenTest/Autotest for Java 和 JUnit 的东西

regex - 匹配除 mod_rewrite 中的一个之外的所有子域

java - 消除String java中的一个char

c++ - 错误 : conversion from 'const char [5]' to non-scalar type in c++