我有一个由两列组成的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
答案 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类方法,但不需要这样做。
如果要在不是当前目录的目录中执行此操作,请更改当前目录或添加文件名的路径。