• Ruby学习笔记(一)


    在做实验的时候,由于每次都要手工修改文件夹的名字,实在是给自己添了太多的麻烦,为了摆脱手工修改的困恼,于是产生了一个使用程序批量修改文件夹名字的好主意。为了最终实现这个目标,自然需要选择一种合适的脚本语言,恰好目前对Ruby十分感兴趣,于是“兴趣+需求”,诞生了一个不算过于丑陋的Ruby程序(自以为)。

    (一)功能需求

    首先来说一下我的需求:在程序运行的根目录(记为LDAModel)下有50个子文件夹(名字分别为21-70,为什么不是从1开始呢?),而每个子文件夹下又有若干个子文件夹,其名字分为两类,分别是20和20(i),如下图所示:

    而其中名为20的文件夹并不一定存在,如果不存在的话则在每次程序运行的时候将20(i)中的一个转换为20。

    此外,20(i)的文件夹中的数据可能会出现错误,如果其中的文件数量小于6,则无法使用,因此应该将这类文件夹直接删除!

     (二)代码及说明

     接下来展示一下满足上述需求的代码:

     1 require 'fileutils'
     2 def rename (folder)
     3     # Dir.foreach(folder) do |file|
     4     #     puts file if File.directory?(file) && Dir.
     5     # end
     6     queryFolders = Dir.entries( folder ).delete_if {|e| e=~ /^..*/ || !File.directory?(e)}
     7     queryFolders.each{ |e|
     8         tFolder = Dir.entries(e).delete_if{ |e| e=~/^..*/}    
     9         tFolder.each{|model| 
    10             FileUtils.rm_rf("./#{e}/#{model}") if Dir.entries("./#{e}/#{model}").delete_if{|e1| e=~ /^..*/ }.length()<6
    11         }
    12         # break;
    13         next if tFolder.include?("20")
    14         if (unRenameFolder = tFolder.each{|e| e=~ /20(d{1,3})/}).length > 0
    15             File.rename("./#{e}/#{unRenameFolder[0]}","./#{e}/20")
    16         end
    17     }
    18 end
    19 
    20 # puts File.dirname(__FILE__)
    21 
    22 rename(File.dirname(__FILE__))
    View Code

    需要注意的是该代码仅在Mac系统下通过测试,其他的环境的可行性还有待证明。

    下面再来简要的分析一下上述代码

    这部分代码主要包括三个部分,第一部分是引用库FILEUTILS,第二部分是定义函数,第三部分则是调用函数

    rename(File.dirname(__FILE__))

    先来说说第三部分(代码的最后一行),其中最需要说明的是__FILE__主要指的是当前文件所在的目录,而不是当前运行的目录。如果需要获得当前运行的目录,则需要使用Dir.pwd(熟悉Linux的朋友应该很熟悉吧,pwd哦,不是password哦~~嘻嘻)

    接下来我们再回头看一下函数定义部分,为了实现上述功能,首先找到第一层的子文件夹(即图中21,22,23那些文件夹),并去掉其中的隐藏内容和普通文件(我们需要的是文件夹啊)。于是有

    queryFolders = Dir.entries( folder ).delete_if {|e| e=~ /^..*/ || !File.directory?(e)}

    其中,使用正则表达式滤除隐藏文件(Mac系统下会有一些隐藏文件干扰我们的正常操作,但是该方法是否在Windows下起作用呢?这是我的疑虑),用File.directory?滤除普通文档。在此不得不感叹,Ruby作为一门动态语言就是灵活啊,想把对象看作是字符串就是字符串,想看做是文件就是文件。正如N年前,某位张姓师兄的所说“一行代码搞定!”,古之人诚不余欺啊。

    接下来就是遍历了,each解决。

    接下来判断每个文件夹中是否有6个以上的文件,如果没有则删除,对于文件夹的删除有两种,一种是Dir.rmdir(),另一种则是本文所使用的方法—FileUtils.rm_rf,前一种只能删除空空如也的文件夹,而后者的杀伤力更大,直接斩草除根,而这正是我们所需要的方式。

    相信很多人注意到了,调用FileUtils.rm_rf和Dir.entries方法时,填充的参数时"./#{e}/#{model}",如果model是一个文件的话,为什么不直接调用

    FileUtils.rm_rf(model)和Dir.entries(model)

    说实话,如果使用Java的话,确实只需要如此即可实现了。但是在Ruby中,经过笔者的多次尝试,总是得到

     No such file or directory 

    如果在此行使用Dir.pwd,可以清晰地看到当前的运行目录是LDAModel(也就是21,22它们的父目录),此时使用Dir.entries(model),相当于在

    FileUtils.rm_rf("LDA/20")
    Dir.entries("LDA/20")

    做操作,由于这两个路径是不存在的,因此无法执行正确的代码。

    虽然问题找到了,但是笔者仍然对Ruby的运行机制有很多疑问,希望各位大牛不吝赐教~~~

    最后需要说明的是,有很多书中都提到可以使用Find来遍历文件。事实上,这一招实在是不满足笔者的基本需求,因为Find遍历的是文件夹下的所有文件和目录(似乎是深度优先的,不过记不清了),因此被笔者直接无视!

     

  • 相关阅读:
    关于产品那些事
    关于“编程的本质”的探讨
    分享一款在线贝塞尔曲线调试器
    HTML、CSS、JS对unicode字符的不同处理
    HTTP Content-Disposition Explanation [ from MDN ]
    认证 (authentication) 和授权 (authorization) 的区别
    事件驱动引擎会取代多线程编程吗
    你所不知道的JSON
    都有哪些特殊而实用的的搜索引擎?
    巨头们的GitHub仓库整理
  • 原文地址:https://www.cnblogs.com/supakito/p/3660647.html
Copyright © 2020-2023  润新知