我正在尝试找一种简单的方法来编辑文件中的每一行,而我在理解如何使用File
类时遇到了一些麻烦。
我要编辑的文件有几百行,每行都有逗号分隔值。我只对每行中的第一个值感兴趣,并且我想在第一个值之后删除所有值。我试着做以下事情:
File.open('filename.txt', 'r+') do |file|
file.each_line { |line| line = line.split(",")[0] }
file.write
file.close
end
这不起作用,因为File.write
方法要求将内容写为参数。
有人可以告诉我如何达到预期的效果吗?
答案 0 :(得分:23)
更好的解决方案之一(也是最安全的)是使用TempFile创建临时文件,并在完成后将其移至原始位置(使用FileUtils):
require 'fileutils'
require 'tempfile'
t_file = Tempfile.new('filename_temp.txt')
File.open("filename.txt", 'r') do |f|
f.each_line{|line| t_file.puts line.split(",")[0].to_s }
end
t_file.close
FileUtils.mv(t_file.path, "filename.txt")
答案 1 :(得分:11)
另一种修改文件的方法是使用-i
开关
ruby -F"," -i.bak -ane 'puts $F[0]' file
答案 2 :(得分:5)
使用代码进行文件处理与我们在文本编辑器中编辑文件时的操作大不相同。操作系统提供的文件操作在这方面非常有限(由于许多,部分历史原因 - 想想磁带)。
简而言之,您应该创建另一个文件并向其写入数据(Mike提供了相应的代码),或者将整个文件加载到内存中(如果您的文件很大,这可能是个坏主意)并用处理后的数据覆盖它。
只是为了练习,这里是你如何实际编辑文件的方法。如你所见,不是最漂亮的景象:
File.open('foo', 'r+') do |file|
write_pos = 0
file.each do |line|
word = line.chomp.split(',').first
read_pos = file.pos
file.pos = write_pos
file.puts word
write_pos = file.pos
file.pos = read_pos
end
file.truncate write_pos
end
答案 3 :(得分:4)
我认为你误解了这一行
file.each_line { |line| line = line.split(",")[0].to_s }
确实如此。它需要一行,在逗号上拆分,取第一个值,将其转换为字符串(它已经是),将结果赋给块本地变量'line'。那么?答案 4 :(得分:2)
接受答案的问题是它修改了文件权限和所有权(注意这一点)。
另一种方法是在Ruby中使用inplace编辑(而不是从命令行):
#!/usr/bin/ruby
def inplace_edit(file, bak, &block)
old_stdout = $stdout
argf = ARGF.clone
argf.argv.replace [file]
argf.inplace_mode = bak
argf.each_line do |line|
yield line
end
argf.close
$stdout = old_stdout
end
inplace_edit 'test.txt', '.bak' do |line|
line = line.gsub(/search1/,"replace1")
line = line.gsub(/search2/,"replace2")
print line unless line.match(/something/)
end
如果您不想创建备份,请将“.bak”更改为“”。