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

Ruby 如何从列表中查找和替换文件名列表,ruby,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_

我有一个由两列组成的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] }
csv_lines = CSV.open(input_file_name,
                     headers: true,
                     col_sep: "\b")
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
这给了我:

 [{"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

您可能希望将CSV加载到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] }
csv_lines = CSV.open(input_file_name,
                     headers: true,
                     col_sep: "\b")
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
这将为您提供所有带有标题的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] }
csv_lines = CSV.open(input_file_name,
                     headers: true,
                     col_sep: "\b")
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
我想你已经知道如何重新命名了

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


另外,您可以在循环中添加异常处理程序,以防输入文件中缺少任何文件

您可能希望将CSV加载到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] }
csv_lines = CSV.open(input_file_name,
                     headers: true,
                     col_sep: "\b")
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
这将为您提供所有带有标题的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] }
csv_lines = CSV.open(input_file_name,
                     headers: true,
                     col_sep: "\b")
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
我想你已经知道如何重新命名了

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


另外,您可以在循环中添加异常处理程序,以防输入文件中缺少任何文件

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

重命名.csv新文件,旧文件

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不能有任何空格,而是使用逗号呢?我对您的输入文件也有点困惑,但假设是一个带有逗号分隔且没有标题的csv文件,您可以这样做:

重命名.csv新文件,旧文件

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不能有任何空格,而是使用逗号?假设您的文件只包含以下五行:

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
_
在空目录中:

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

Dir.entries(".")
  #=> [".", "..", "my_file.txt"] 
arr.each { |name| File.write(name,'') }

Dir.entries(".")
  #=> [".", "..", "Cfda", "Cyffa", "Cyfsaff", "my_file.txt"] 
为了进行测试,让我们创建数组给定的空文件:

arr = ["Cfda", "Cyffa", "Cyfsaff"]
但不在同一目录中:

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

Dir.entries(".")
  #=> [".", "..", "my_file.txt"] 
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"]
您可以使用类方法,但没有必要这样做


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

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

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
_
在空目录中:

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

Dir.entries(".")
  #=> [".", "..", "my_file.txt"] 
arr.each { |name| File.write(name,'') }

Dir.entries(".")
  #=> [".", "..", "Cfda", "Cyffa", "Cyfsaff", "my_file.txt"] 
为了进行测试,让我们创建数组给定的空文件:

arr = ["Cfda", "Cyffa", "Cyfsaff"]
但不在同一目录中:

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

Dir.entries(".")
  #=> [".", "..", "my_file.txt"] 
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"]
您可以使用类方法,但没有必要这样做


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

您查看过吗?你所说的转换实际文件名是什么意思?是的,我看到了。问题是,我想根据我在问题中输入的哈希值,尝试将旧文件名转换为新文件名。实际文件名是文件的文件名,而不是将散列中的旧名称转换为散列中的新名称。使用@tuo的答案进行编辑有什么意义?顺便说一句,该答案不正确,因为它会重复将每行的旧名称重命名为新名称?编辑只是为了澄清问题,有时是为了展示你的尝试。所以我的编辑是为了展示我的尝试。我不知道问题出在哪里……你是说你试图修改@tuo的答案,但仍然不起作用,还是在修改了tuo的答案后,这里给出了正确的答案?注意File.rename和tuo的不一样。你看过吗?你所说的转换实际文件名是什么意思?是的,我看到了。问题是,我想根据我在问题中输入的哈希值,尝试将旧文件名转换为新文件名。实际文件名是文件的文件名,而不是将散列中的旧名称转换为散列中的新名称。使用@tuo的答案进行编辑有什么意义?顺便说一句,该答案不正确,因为它会重复将每行的旧名称重命名为新名称?编辑只是为了澄清问题,有时是为了展示你的尝试。所以我的编辑是为了展示我的尝试。我不知道问题出在哪里……你是说你试图修改@tuo的答案,但仍然不起作用,还是在修改了tuo的答案后,这里给出了正确的答案?注意:File.rename不是
和拓的不一样。实际上,这是我搞不懂的重命名工作。我已经试过上面的方法了-这可能有效吗?我不确定如何循环遍历包含文件名的文件夹并找到旧名称?希望从我的更新代码来看这是有意义的。实际上,这是我搞不懂的重命名工作。我已经试过上面的方法了-这可能有效吗?我不确定如何循环遍历包含文件名的文件夹并找到旧名称?希望我的更新代码能让你明白,谢谢。这是否意味着File.rename将看到旧文件名,然后将其替换为与之“配对”的相应新文件名?是的,它将在csv中使用旧名称,并将其替换为新名称。如果该文件不存在,它将在本例中对其进行解救。如果您不存在,那么如果该文件不存在,它将给出SystemCallError。谢谢。这是否意味着File.rename将看到旧文件名,然后将其替换为与之“配对”的相应新文件名?是的,它将在csv中使用旧名称,并将其替换为新名称。如果文件不存在,它将在这种情况下拯救它。如果你不存在,那么如果文件不存在,它将给出一个SystemCallError。感谢yu给出了一个很好的回答,并做了很好的解释@Nabeelas的回答很有效,所以得到了提示,但你的回答也很好。谢谢你的回答,并且解释得很好@纳比拉斯的答案很有效,所以得到了选票,但你的答案也被提高了