为什么不gsub! 改变我的文件?
我正在尝试对目录中的所有文本文件进行简单的查找/替换,修改[RAVEN_START:
任何实例[RAVEN_START:
通过[RAVEN_START:
插入一个字符串(在本例中为“raven was here”)。
这是整个ruby程序:
#!/usr/bin/env ruby require 'rubygems' require 'fileutils' #for FileUtils.mv('your file', 'new location') class RavenParser rawDir = Dir.glob("*.txt") count = 0 rawDir.each do |ravFile| #we have selected every text file, so now we have to search through the file #and make the needed changes. rav = File.open(ravFile, "r+") do |modRav| #Now we've opened the file, and we need to do the operations. if modRav lines = File.open(modRav).readlines lines.each { |line| if line.match /\[RAVEN_START:.*\]/ line.gsub!(/\[RAVEN_START:/, 'raven was here '+line) count = count + 1 end } printf("Total Changed: %d\n",count) else printf("No txt files found. \n") end end #end of file replacing instructions. end # S end
程序运行并编译正常,但是当我打开文本文件时,文件中的任何文本都没有变化。 正确count
增量(即,它等于[RAVEN_START:
跨所有文件的实例数],但实际替换未能发生(或至少不保存更改)。
我的语法是在gsub!
上的gsub!
不正确的? 我做错了什么吗?
您正在读取数据,更新数据,然后忽略将数据写回文件。 你需要这样的东西:
# And save the modified lines. File.open(modRav, 'w') { |f| f.puts lines.join("\n") }
紧接在此之前或之后:
printf("Total Changed: %d\n",count)
正如下面的DMG所说,只是覆盖文件并不是特别偏执,因为你可能会在写入过程中被中断并丢失数据。 如果你想成为偏执狂(我们所有人都应该是因为他们真的想要我们),那么你想写一个临时文件然后做一个primefaces重命名来替换原来的新文件。 重命名通常仅在您保留在单个文件系统中时才起作用,因为无法保证OS的临时目录(默认情况下Tempfile
使用该目录)与modRav
位于同一文件系统上,因此File.rename
可能不是一个选项除非采取预防措施,否则为Tempfile
。 但是Tempfile
构造函数接受一个tmpdir
参数,所以我们保存了:
modRavDir = File.dirname(File.realpath(modRav)) tmp = Tempfile.new(modRav, modRavDir) tmp.write(lines.join("\n")) tmp.close File.rename(tmp.path, modRav)
您可能希望将其粘贴在单独的方法(也许是safe_save(modRav, lines)
)中,以避免进一步混乱您的块。
-
没有
gsub!
在post中(标题和问题除外)。 我实际上建议不要使用gsub!
,而是使用gsub
的结果 – 避免可变性可以帮助减少一些微妙的错误。 -
从文件流读取 到 String的行是一个副本 ,修改它不会影响文件的内容。 (一般的方法是读取一条线,处理线,然后写入线。或者一次完成所有操作:读取所有线,处理所有线,写入所有处理过的线。在任何一种情况下,都没有任何东西被写回文件在post中的代码;-)
快乐的编码。
你没有使用gsub!
,你正在使用gsub
。 gsub!
和gsub
不同的方法,一个替换对象本身,另一个替换然后分别返回结果。
改变这个
line.gsub(/\[RAVEN_START:/, 'raven was here '+line)
对此:
line.gsub!(/\[RAVEN_START:/, 'raven was here '+line)
或这个:
line = line.gsub(/\[RAVEN_START:/, 'raven was here '+line)
有关详细信息,请参阅String#gsub