如何从列表中查找和替换文件名列表

时间:2016-01-01 16:22:16

标签: ruby

我有一个由两列组成的CSV文件。

一列是旧文件名,另一列是新文件名。

我想用新文件名替换文件夹中的实际文件名。

我看了很多,但却找不到如何做到这一点。

我的输入文件是:

    New Old
Dys.FSA_BB_NEW_0204_Sp_5_HBG_fq.gz.res  Cfda
Dys.FSC_Sp_BB_LC_0028_R1_30_HBG_fq.gz.res   Cyffa
Dys_BB_NEW_0177_Sp_FSD.5_HBG_fq.gz.res  Cyfsaff
Dys_FSE.BB_AM_0104_Sp_5_HBG_fq.gz.res   afffa
Dys_FSF.AM_0068_Sp_5_HBG_fq.gz.res  Cvdsd
Dys_FSG.BB_LC_261_Sp_15_HBG_fq.gz.res   vsvds0
Dys_FSH.BB_LC_0047_Sp_10_HBG_fq.gz.res  Cyto_vds.0
Dys_FastB_BB_LC_0028_Sp_15_HBG_fq.gz.res    Cvsv
Dys_FSA_OC_AH_255_E_B1_Biopsy_30_LBG_fq.gz.res  AneupvsvEFS
Dys_FSC_OC_UC_025_E_B1_Biopsy_25_LBG_fq.gz.res  vdvsupDysplasticBEFS
Dys_FSD_BB_POR_0028_Biopsy_30_HBG_fq.gz.res 24vdvdS
Dys_FSH_BB_NEW_0097_Biopsy_70_HBG_fq.gz.res Avdsgf3
Dys_FSI_BB_AM_0003_Biopsy_60_LBG_fq.gz.res  AnfdsfdsFS

我想我必须先从csv创建一个哈希数组,使用类似的东西:

require 'csv'
csv_data = CSV.read '/Users/sebastianzeki/Desktop/tbb.csv'
headers = csv_data.shift.map {|i| i.to_s }
string_data = csv_data.map {|row| row.map {|cell| cell.to_s } }
array_of_hashes = string_data.map {|row| Hash[*headers.zip(row).flatten] }

这给了我:

 [{"New"=>"Dys.FSA_BB_NEW_0204_Sp_5_HBG_fq.gz.res", "Old"=>"Cfda"}, {"New"=>"Dys.FSC_Sp_BB_LC_0028_R1_30_HBG_fq.gz.res", "Old"=>"Cyffa"}, {"New"=>"Dys_BB_NEW_0177_Sp_FSD.5_HBG_fq.gz.res", "Old"=>"Cyfsaff"}, {"New"=>"Dys_FSE.BB_AM_0104_Sp_5_HBG_fq.gz.res", "Old"=>"afffa"}, {"New"=>"Dys_FSF.AM_0068_Sp_5_HBG_fq.gz.res", "Old"=>"Cvdsd"}, {"New"=>"Dys_FSG.BB_LC_261_Sp_15_HBG_fq.gz.res", "Old"=>"vsvds0"}, {"New"=>"Dys_FSH.BB_LC_0047_Sp_10_HBG_fq.gz.res", "Old"=>"Cyto_vds.0"}, {"New"=>"Dys_FastB_BB_LC_0028_Sp_15_HBG_fq.gz.res", "Old"=>"Cvsv"}, {"New"=>"Dys_FSA_OC_AH_255_E_B1_Biopsy_30_LBG_fq.gz.res", "Old"=>"AneupvsvEFS"}, {"New"=>"Dys_FSC_OC_UC_025_E_B1_Biopsy_25_LBG_fq.gz.res", "Old"=>"vdvsupDysplasticBEFS"}, {"New"=>"Dys_FSD_BB_POR_0028_Biopsy_30_HBG_fq.gz.res", "Old"=>"24vdvdS"}, {"New"=>"Dys_FSH_BB_NEW_0097_Biopsy_70_HBG_fq.gz.res", "Old"=>"Avdsgf3"}, {"New"=>"Dys_FSI_BB_AM_0003_Biopsy_60_LBG_fq.gz.res", "Old"=>"AnfdsfdsFS"}]

那么我现在如何将文件夹中的实际文件名转换为新文件夹(在同一文件夹中)?

使用@ tuo的答案编辑

csv_lines = CSV.open('/Users/sebastianzeki/Desktop/tbb.csv',
                     headers: true,
                     col_sep: "\b")


filenames = Dir.glob("/Users/sebastianzeki/myfolder/*")

csv_lines.each do |row|
  old_name = row['Old']
  new_name = row['New']
  filenames.each do |filename|
  File.rename(old_name,new_name)
    end
end

3 个答案:

答案 0 :(得分:2)

您可能希望将CSV加载到CSV :: Rows中,如下所示:

csv_lines = CSV.open(input_file_name,
                     headers: true,
                     col_sep: "\b")

这将为您提供带有标题的所有csv行,您可以像这样迭代这些行:

path = '/your/dir/path/'

csv_lines.each do |row|
  old_name = row['Old']
  new_name = row['New']

  #TODO: find the file with the old name and update it to the new one 

  #EDIT: it can be done like this:
  File.rename(path + old_name, path + new_name)
end

我猜你已经知道如何进行重命名工作了。 :)

编辑:我添加了重命名到我的代码中。无需扫描每个循环中的文件夹。您只需要找到一个文件并一次重命名。

PS。如果输入文件中有任何丢失的文件,您可以在循环中添加异常处理程序。

答案 1 :(得分:1)

我的输入文件也有点困惑,但假设一个逗号分隔且没有标题的CSV文件你可以这样做:

rename.csv (new_file,old_file)

foo_file_one,file_one
foo_file_two,file_two

假设rename.csv和您要重命名的文件位于同一个文件夹中

require 'csv'

rename_list = CSV.parse(File.read('rename.csv'))

rename_list.each do |new, old|
  File.rename(old, new) rescue ''
end

但这是否意味着你的rename.csv不能有任何空格但是使用逗号

答案 2 :(得分:1)

假设您的文件只包含以下五行:

my_data = <<_ 
    New Old
Dys.FSA_BB_NEW_0204_Sp_5_HBG_fq.gz.res  Cfda
Dys.FSC_Sp_BB_LC_0028_R1_30_HBG_fq.gz.res   Cyffa
Dys_BB_NEW_0177_Sp_FSD.5_HBG_fq.gz.res  Cyfsaff
Dys_FSE.BB_AM_0104_Sp_5_HBG_fq.gz.res   afffa
_

让我们创建文件

FName = "my_file.txt"

在一个空目录中:

File.write(FName, my_data)
  #=> 201

Dir.entries(".")
  #=> [".", "..", "my_file.txt"] 

为了测试,让我们创建(空)数组给出的文件:

arr = ["Cfda", "Cyffa", "Cyfsaff"]

(但不是“afffa”)在同一目录中:

arr.each { |name| File.write(name,'') }

Dir.entries(".")
  #=> [".", "..", "Cfda", "Cyffa", "Cyfsaff", "my_file.txt"] 

我们现在可以逐行将文件FName读入数组,丢弃标题并使用“旧名称”给出的名称重命名当前目录中的文件:

File.readlines(FName)[1..-1].each do |s|
  new, old = s.chomp.split
  File.rename(old, new) if File.exist?(old)
end

Dir.entries(".")
  #=> [".", "..", "Dys.FSA_BB_NEW_0204_Sp_5_HBG_fq.gz.res",
  #    "Dys.FSC_Sp_BB_LC_0028_R1_30_HBG_fq.gz.res",
  #    "Dys_BB_NEW_0177_Sp_FSD.5_HBG_fq.gz.res", "my_file.txt"]

您可以使用CSV类方法,但不需要这样做。

如果要在不是当前目录的目录中执行此操作,请更改当前目录或添加文件名的路径。