Module: FileUtils

Defined in:
lib/nano/fileutils/wc.rb,
lib/nano/fileutils/head.rb,
lib/nano/fileutils/tail.rb,
lib/nano/fileutils/slice.rb,
lib/nano/fileutils/which.rb,
lib/nano/fileutils/safe_ln.rb,
lib/nano/fileutils/whereis.rb

Constant Summary collapse

Win32Exts =
%w{.exe .com .bat}

Class Method Summary collapse

Class Method Details

.head(filename, lines = 10) ⇒ Object

In block form, yields the first number of ((lines)) of file ((filename)). In non-block form, it returns an array of the first number of ((lines)).

# Returns first 10 lines of 'myfile'
FileUtils.head("myfile")


14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/nano/fileutils/head.rb', line 14

def head(filename,lines=10) #:yield:
  a = []
  IO.foreach(filename){|line|
      break if lines <= 0
      lines -= 1
      if block_given?
        yield line
      else
        a << line
      end
  }
  return a.empty? ? nil : a
end

.safe_ln(*args) ⇒ Object

Attempt to do a normal file link, but fall back to a copy if the link fails.



9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/nano/fileutils/safe_ln.rb', line 9

def safe_ln(*args)
  if @link_not_supported
    FileUtils.cp(*args)
  else
    begin
      FileUtils.ln(*args)
    rescue Errno::EOPNOTSUPP
      @link_not_supported = true
      FileUtils.cp(*args)
    end
  end
end

.slice(filename, from, to) ⇒ Object

In block form, yields lines ((from))-((to)). In non-block form, returns an array of lines ((from))-((to)).

# Returns lines 8-12 of 'myfile'
FileUtils.body("myfile",8,12)

– Credit goes to Shashank Date, via Daniel Berger. ++



17
18
19
# File 'lib/nano/fileutils/slice.rb', line 17

def slice(filename,from,to) #:yield:
  IO.readlines(filename)[from-1..to-1]
end

.tail(filename, lines = 10) ⇒ Object

In block form, yields the last number of ((lines)) of file ((filename)). In non-block form, it returns the lines as an array.

Note that this method slurps the entire file, so I don’t recommend it for very large files. If you want an advanced form of ((tail)), I suggest using file-tail, by Florian Frank (available on the RAA). And no tail -f.

# Returns last 3 lines of 'myfile'
FileUtils.tail("myfile",3)


19
20
21
# File 'lib/nano/fileutils/tail.rb', line 19

def tail(filename,lines=10) #:yield
  IO.readlines(filename).reverse[0..lines-1].reverse
end

.wc(filename, option = 'all') ⇒ Object

With no arguments, returns a four element array consisting of the number of bytes, characters, words and lines in filename, respectively.

Valid options are bytes, characters (or just ‘chars’), words and lines.

# Return the number of words in 'myfile'
FileUtils.wc("myfile",'words')


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/nano/fileutils/wc.rb', line 19

def wc(filename,option='all')
  option.downcase!
  valid = %w/all bytes characters chars lines words/

  unless valid.include?(option)
      raise "Invalid option: '#{option}'"
  end

  n = 0
  if option == 'lines'
      IO.foreach(filename){ n += 1 }
      return n
  elsif option == 'bytes'
      File.open(filename){ |f|
        f.each_byte{ n += 1 }
      }
      return n
  elsif option == 'characters' || option == 'chars'
      File.open(filename){ |f|
        while f.getc
            n += 1
        end
      }
      return n
  elsif option == 'words'
      IO.foreach(filename){ |line|
        n += line.split.length
      }
      return n
  else
      bytes,chars,lines,words = 0,0,0,0
      IO.foreach(filename){ |line|
        lines += 1
        words += line.split.length
        chars += line.split('').length
      }
      File.open(filename){ |f|
        while f.getc
            bytes += 1
        end
      }
      return [bytes,chars,words,lines]
  end
end

.whereis(prog, path = ENV['PATH']) ⇒ Object

In block form, yields each ((program)) within ((path)). In non-block form, returns an array of each ((program)) within ((path)). Returns ((nil)) if not found.

On the MS Windows platform, it looks for executables ending with .exe, .bat and .com, which you may optionally include in the program name.

File.whereis("ruby") -> ['/usr/local/bin/ruby','/opt/bin/ruby']


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/nano/fileutils/whereis.rb', line 25

def whereis(prog, path=ENV['PATH']) #:yield:
  dirs = []
  path.split(File::PATH_SEPARATOR).each{|dir|
      # Windows checks against specific extensions
      if File::ALT_SEPARATOR
        if prog.include?('.')
            f = File.join(dir,prog)
            if File.executable?(f) && !File.directory?(f)
              if block_given?
                  yield f.gsub(/\//,'\\')
              else
                  dirs << f.gsub(/\//,'\\')
              end
            end
        else
            Win32Exts.find_all{|ext|
              f = File.join(dir,prog+ext)
              if File.executable?(f) && !File.directory?(f)
                  if block_given?
                    yield f.gsub(/\//,'\\')
                  else
                    dirs << f.gsub(/\//,'\\')
                  end
              end
            }
        end
      else
        f = File.join(dir,prog)
        # Avoid /usr/lib/ruby, for example
        if File.executable?(f) && !File.directory?(f)
            if block_given?
              yield f
            else
              dirs << f
            end
        end
      end
  }
  dirs.empty? ? nil : dirs
end

.which(prog, path = ENV['PATH']) ⇒ Object

Looks for the first occurrence of program within path.

On the MS Windows platform, it looks for executables ending with .exe, .bat and .com, which you may optionally include in the program name. Returns nil if not found.

– The which() method was adopted from Daniel J. Berger, via PTools which in in turn was adopted fromt the FileWhich code posted by Michael Granger on www.rubygarden.org. ++



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/nano/fileutils/which.rb', line 28

def which(prog, path=ENV['PATH'])
  path.split(File::PATH_SEPARATOR).each {|dir|
    # Windows checks against specific extensions
    if File::ALT_SEPARATOR
      ext = Win32Exts.find{|ext|
        if prog.include?('.') # Assume extension already included
          f = File.join(dir,prog)
        else
          f = File.join(dir,prog+ext)
        end
        File.executable?(f) && !File.directory?(f) 
      }
      if ext
        # Use backslashes, not forward slashes
        if prog.include?('.') # Assume extension already included
          f = File.join( dir, prog ).gsub(/\//,'\\')
        else
          f = File.join( dir, prog + ext ).gsub(/\//,'\\')
        end
        return f
      end
    else
      f = File.join(dir,prog)
      # Avoid /usr/lib/ruby, for example
      if File.executable?(f) && !File.directory?(f)
        return File::join( dir, prog )
      end
    end
  }
  nil
end