【问题标题】:Remove certain characters from several files从多个文件中删除某些字符
【发布时间】:2014-04-24 13:36:28
【问题描述】:

我想从文件夹中的多个文件中删除以下字符。我到目前为止是这样的:

str.delete! '!@#$%^&*() 

我认为这将有助于删除字符。我需要做什么才能让它遍历文件夹中的所有文件?

【问题讨论】:

  • 你想对输出做什么?如果您不对其进行任何操作,被替换的字符串将原地消失。
  • 您想从文件名或文件内容中删除这些字符(如果它们是文本文件)?
  • 我想从文件内容中删除它们。基本上,我只需要它遍历目录中的所有文件,从所有文件中删除这些字符的任何实例,然后保持文件名相同。

标签: ruby file


【解决方案1】:

您澄清了您的问题,声明您想从目录中文件的 内容 中删除某些字符。我创建了一种直接的方式来遍历目录(以及可选的子目录)并从文件内容中删除指定的字符。我像你一样使用String#delete。如果您想删除更高级的模式,您可能需要使用正则表达式将其更改为 String#gsub

下面的示例将遍历相对于当前工作目录的tmp 目录(和所有子目录),并删除找到的文件中所有出现的!$@。你当然也可以传递绝对路径,例如C:/some/dir。请注意,我没有过滤文件,我假设那里都是文本文件。如果您愿意,当然可以添加文件扩展名检查。

def replace_in_files(dir, chars, subdirs=true)
  Dir[dir + '/*'].each do |file|
    if File.directory?(file) # Traverse inner directories if subdirs == true
      replace_in_files(file, chars, subdirs) if subdirs
    else # Replace file contents
      replaced = File.read(file).delete(chars)
      File.write(file, replaced)
    end
  end
end

replace_in_files('tmp', '!$@')

【讨论】:

  • 您好,感谢您的回复。出于某种原因,我无法使其正常工作。我是否只是将脚本与我希望它更改并运行的文本文件放在同一目录中?还是我需要创建一个绝对路径。抱歉,我需要更多帮助 :(
  • @user3434301 您可以将脚本放置在任何位置,并且可以使用绝对路径作为参数(例如:"C:/users/yourname/desktop/folder")或相对路径(例如,"folder",如果您将桌面上的脚本和“文件夹”是桌面上的文件夹)。不要把它放在同一个目录下,那么它也会替换脚本源文件中的字符:) 把它放在父目录中(例如,如果你的文件在 C:/data/files,把脚本放在 C: /data 并以 'files' 作为第一个参数调用它)。
  • 您好 Daniël,再次感谢您的回复。我将脚本中的每个 dir 实例更改为文件夹的名称(TestX),它会引发错误。除了脚本中的 dir 之外,我是否应该更改某些内容?我只是将文件夹的名称放在双引号“TextX”中,然后出现以下错误:语法错误,意外',',期望输入结束 def replace_in_files("TextX", chars, subdirs=true)跨度>
  • 什么?天哪,没有。您只需要替换最后一行的'tmp'...因此,如果您将脚本放在C:/data 中,并且您有一个包含文本文件的文件夹C:/data/files,则将'tmp' 替换为'files' 和运行脚本(您将其放在C:/data 中)。
【解决方案2】:

我认为这可能有效,尽管我对 Ruby 中的 Dir 类有点不放心。

Dir.foreach('/path/to/dir') do |file|
  file.delete '!@#$%^&*() 
end

您的问题在这里有一个更通用的版本:Iterate through every file in one directory

希望会有一个更彻底的答案,但也许这会让你到达你需要的地方。

【讨论】:

  • 呃,file 变量在这里只是一个字符串;文件的文件名。调用.delete 会从文件名字符串中删除指定的字符。但是,它使实际文件名保持不变。这将需要您重命名文件。这也不会从文件内容中删除这些字符(我不确定应该发生什么,问题不清楚)。
  • 所以基本上我想保留文件名,只需从实际文件中删除指定的字符。抱歉,如果不清楚。
【解决方案3】:
Dir.foreach('filepath') do |f|
    next if Dir.exists?(f)
    file = File.new("filepath/#{f}",'r+')
    text = file.read.delete("'!@#$%^&*()")
    file.rewind
    file.write(text)
    file.close
end

你做不到的原因

file.write(file.read.delete("'!@#$%^&*()"))

file.read 是否在文本末尾留下“光标”。而不是覆盖文件,您将追加到文件中,这不是您想要的。

您还可以向 File 类添加一个方法,将光标移动到文件的开头。

class File
    def newRead
        data = self.read
        self.rewind
        data
    end
end

Dir.foreach('filepath') do |f|
    next if Dir.exists?(f)
    file = File.new("filepath/#{f}",'r+')
    file.write(file.newRead.delete("'!@#$%^&*()"))
    file.close
end

【讨论】:

  • 嘿乔丹,感谢您的回复。我试图使用以下代码:Dir.foreach('filepath') do |f| next if Dir.exists?(f) file = File.new("filepath/#{f}",'r+') text = file.read.delete("'!@#$%^&*()") file.rewind file.write(text) file.close end 我将文件路径添加到 dir.foreach 但是当我将它添加到 file.new 时它会抛出错误。它应该看起来像这样吗? file = File.new("\Users\Tim\Test/#{f}", 'r+') 还是我做错了什么?我用的是win7
  • 在文件路径中,使用'/',而不是'\'。此外,请确保您的 ruby​​ 文件位于与您要删除字符的目录不同的目录中。希望有帮助
猜你喜欢
  • 2015-05-18
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多