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

(一)功能需求

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

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

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

(二)代码及说明

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

 require 'fileutils'
def rename (folder)
# Dir.foreach(folder) do |file|
# puts file if File.directory?(file) && Dir.
# end
queryFolders = Dir.entries( folder ).delete_if {|e| e=~ /^\..*/ || !File.directory?(e)}
queryFolders.each{ |e|
tFolder = Dir.entries(e).delete_if{ |e| e=~/^\..*/}
tFolder.each{|model|
FileUtils.rm_rf("./#{e}/#{model}") if Dir.entries("./#{e}/#{model}").delete_if{|e1| e=~ /^\..*/ }.length()<6
}
# break;
next if tFolder.include?("")
if (unRenameFolder = tFolder.each{|e| e=~ /20\(d{1,3}\)/}).length > 0
File.rename("./#{e}/#{unRenameFolder[0]}","./#{e}/20")
end
}
end # puts File.dirname(__FILE__) rename(File.dirname(__FILE__))

需要注意的是该代码仅在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遍历的是文件夹下的所有文件和目录(似乎是深度优先的,不过记不清了),因此被笔者直接无视!

Ruby学习笔记(一)的更多相关文章

  1. Ruby学习笔记4: 动态web app的建立

    Ruby学习笔记4: 动态web app的建立 We will first build the Categories page. This page contains topics like Art, ...

  2. ruby学习笔记(1)-puts,p,print的区别

    ruby学习笔记-puts,p,print的区别 共同点:都是用来屏幕输出的. 不同点:puts 输出内容后,会自动换行(如果内容参数为空,则仅输出一个换行符号):另外如果内容参数中有转义符,输出时将 ...

  3. ruby 学习笔记 1

    写ruby blog  系统的记录下.也是对我学ruby的点滴记录. 先介绍下我的学习环境.系统:ubuntu12.04文档:techotopia ,ruby文档,the hard way learn ...

  4. ruby学习笔记(2)-chomp,chop的区别

    还没开始系统性的学习Ruby,最近在看metasploit框架的exploit会涉及到Ruby脚本,也就硬着头皮一遍查阅资料一遍做些笔记吧. Ruby字符串中存在chop和chomp的内置函数.我在h ...

  5. Ruby学习笔记0708

    #!/usr/bin/env ruby class MegaGreeter attr_accessor :names # 初始化這個物件 def initialize(names = "Wo ...

  6. ruby 学习笔记 2 -变量

    变量 在ruby的世界里,变量有5种,全局变量 局部变量 实例变量 常量 类变量以及伪变量 常用的: 全局: 在全局使用,使用$开头,因为是全局的,所以在任何的代码例子中都可以改变其值,造成混乱,所以 ...

  7. Ruby学习笔记

    #!/usr/bin/ruby puts "Hello, Ruby, what is your name?" $name = STDIN.gets puts "Hi, I ...

  8. Ruby学习笔记(二)

    1.block 代码块 do...end 或 {} 构成一个代码块,就像常见的 .each后面跟的代码块. my_nums = [1,2,3] my_double_nums = my_nums.col ...

  9. Ruby学习笔记之升级ruby的版本

    升级ruby版本,有时候安装ruby的版本过低,需要进行升级,例如安装在centos6.7安装fpm需要ruby版本在1.9以上. 0x00 主机环境如下 [root@test ~]# cat /et ...

  10. Ruby学习笔记7: 添加身份验证(adding Authentication)

    我们已经完成了Category & Product页面内容的增删改查,再加入一个身份验证即可成为一个较完整的Rails App了.本文就来完成这个任务. We now need to give ...

随机推荐

  1. C#调用mmpeg进行各种视频转换的类实例

    本文实例讲述了C#调用mmpeg进行各种视频转换的类.分享给大家供大家参考.具体如下: 这个C#类封装了视频转换所需的各种方法,基本上是围绕着如何通过mmpeg工具来进行视频转换 using Syst ...

  2. Spring学习笔记(二) 初探Spring

    版权声明 笔记出自<Spring 开发指南>一书. Spring 初探 前面我们简单介绍了 Spring 的基本组件和功能,现在我们来看一个简单示例: Person接口Person接口定义 ...

  3. 当安装了ubuntu操作系统怎么也调用不出中文输入法时,可以用以下方式尝试解决。

    卸载 fcitx sudo apt-get remove fcitx 重启 sudo reboot 重新安装 fcitxsudo apt-get isntall fcitx 安装拼音输入法sudo a ...

  4. 远程桌面连接Windows Azure中的Ubuntu虚拟机

    默认情况下,通过Windows Azure创建的ubuntu虚拟机是不能直接连接远程桌面的,只能通过SSH终端连接. 在Windows Azure Portal中创建Ubuntu虚拟机,创建完成后添加 ...

  5. 有关windows dpi适配(c#)

    /// <summary>当前Dpi</summary> public static Int32 Dpi { get; set; } /// <summary>修正 ...

  6. 七牛上图片总是net::ERR_NAME_NOT_RESOLVED

    七牛上图片总是net::ERR_NAME_NOT_RESOLVED >> php这个答案描述的挺清楚的:http://www.goodpm.net/postreply/php/101000 ...

  7. runloop的source

    以上是完整的 CFRunLoop 和 CFRunLoopMode 的结构体源码(太长了我的妈,用不着看完),下面我精简一下,把重要的留下,看如下代码(可以仔细看一下,加深印象): 上面是精简出来比较关 ...

  8. [NOIP补坑计划]NOIP2015 题解&做题心得

    感觉从15年开始noip就变难了?(虽然自己都做出来了……) 场上预计得分:100+100+60~100+100+100+100=560~600(省一分数线365) 题解: D1T1 神奇的幻方 题面 ...

  9. WePy--使用zanUI组件

    因为Wepy 中不能直接引入zanUI组件, 好在还有百度, 参考链接 https://github.com/brucx/wepy-zanui-demo (感谢); 我的做法是将 源码下了下来, 源码 ...

  10. BZOJ 2342 [SHOI2011]双倍回文 (回文自动机)

    题目大意:略 先建出$PAM$ 因为双倍回文串一定是4的倍数,所以找出$PAM$里所有$dep$能整除4的节点 看这个串是否存在一个回文后缀,长度恰好为它的一半,沿着$pre$链往上跳就行了 暴跳可能 ...