# Directory Diff Script

**URL:** <https://www.ruby-forum.com/t/directory-diff-script/61891>\
**Category:** Ruby\
**Created:** [May 29, 2006, 12:59pm UTC](https://www.ruby-forum.com/t/directory-diff-script/61891 "2006-05-29T12:59:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [May 29, 2006, 12:59pm UTC](https://www.ruby-forum.com/t/directory-diff-script/61891/1 "2006-05-29T12:59:23Z")

</div>

Hi,

I am after a directory diff script in Ruby, so I can compare all the  
files in multiple directories. Does anybody know of such a script?

Thanks.

Nick.

---

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [May 30, 2006, 9:31am UTC](https://www.ruby-forum.com/t/directory-diff-script/61891/2 "2006-05-30T09:31:21Z")

</div>

> Hi,
> 
> I am after a directory diff script in Ruby, so I can compare all the  
> files in multiple directories. Does anybody know of such a script?
> 
> Thanks.
> 
> Nick.

I wrote this a while ago. I’m not sure exactly what you are after, but  
maybe you can use it as a starting point:

#!/usr/bin/ruby

IGNORE\_EXT = %w(.scc .exe .xbe .lib .sbr .obj .dat .suo .pdb .res .idb  
.pch)  
IGNORE\_BASE = %w(\_darcs lib vultures buildlog.htm contentmeta.h rdiff)

class String  
def indent  
return “\t” + self.gsub("\n", “\n\t”)  
end  
end

class Diff

```
def diff(f1, f2)
    if f1.respond_to?(:to_ary)
        filelist(f1.to_ary, f2.to_ary)
    else
        if File.directory?(f1) and File.directory?(f2)
            dir(f1,f2)
        elsif File.file?(f1) and File.file?(f2)
            file(f1,f2)
        elsif File.directory?(f1)
            report_directory(f1, f2)
        elsif File.directory?(f2)
            report_directory(f2, f1)
        elsif File.file?(f1)
            report_file(f1, f2)
        elsif File.file?(f2)
            report_file(f2, f1)
        end
    end
end

def file(f1, f2)
    res = `diff #{f1} #{f2}`
    report_diff(f1, f2, res) if res != ""
end

def filelist(l1, l2)
    map = {}
    s = Struct.new(:f1, :f2)
    for f in l1
        next if IGNORE_EXT.include?(File.extname(f))
        next if IGNORE_BASE.include?(File.basename(f))
        next if f[/~\d*$/]
        map[File.basename(f)] = s.new(f, nil)
    end
    for f in l2
        next if IGNORE_EXT.include?(File.extname(f))
        next if IGNORE_BASE.include?(File.basename(f))
        next if f[/~\d*$/]
        b = File.basename(f)
        map[b] = s.new(nil, nil) if not map[b]
        map[b].f2 = f
    end
    for base, files in map
        if !files.f1
            report_missing(files.f2)
        elsif !files.f2
            report_missing(files.f1)
        else
            diff(files.f1, files.f2)
        end
    end
end

def dir(d1, d2)
    diff( Dir.glob(d1 + "/*").collect {|x| x.downcase},
        Dir.glob(d2 + "/*").collect {|x| x.downcase} )
end

# Reporting functions

def report_directory(d, f)
    report(:type_mismatch, "#{d} is a directory, but #{f} is not")
end

def report_file(f, x)
    report(:type_mismatch, "#{f} is a regular file, but #{x} is 

```

not")  
end

```
def report_missing(f)
    report(:missing_file, "#{f} has no corresponding file") if

```

$report\_missing  
end

```
def report_diff(f1, f2, res)
    report(:diff, "\n#{f1} <--> #{f2}\n\n#{res.indent}")
end

def report(type, s)
    puts
    puts s
end

```

end

require ‘optparse’

$report\_missing = false  
$ignore\_case = true

opts = OptionParser.new  
opts.on(’-m’, ‘–missing’, “Report missing files.”) {|val|  
$report\_missing = true;}  
rest = opts.parse(\*ARGV)

Diff.new().diff(rest[0], rest[1])

---

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [May 29, 2006, 11:40pm UTC](https://www.ruby-forum.com/t/directory-diff-script/61891/3 "2006-05-29T23:40:42Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Suraj N. Kurapati wrote:

> Nick wrote:
> 
> > > I am after a directory diff script in Ruby, so I can compare all the  
> > > files in multiple directories. Does anybody know of such a script?
> 
> Yes, it’s called diff. If you want a GUI try meld or kompare.
> 
> [Diff, Patch, and Friends | Linux Journal](http://www.linuxjournal.com/article/1237)

Whoops, I misread the question. Sorry 🙂  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFEe0vQmV9O7RYnKMcRAnEwAJ4qrPD4B0lcgWi07B3T0x8QTyLBngCePtNr  
m273oraSo/EQhPL5GA47jtI=  
=bnMh  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [May 29, 2006, 2:14pm UTC](https://www.ruby-forum.com/t/directory-diff-script/61891/4 "2006-05-29T14:14:49Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Nick wrote:

> I am after a directory diff script in Ruby, so I can compare all the  
> files in multiple directories. Does anybody know of such a script?

Yes, it’s called diff. If you want a GUI try meld or kompare.

[http://www.linuxjournal.com/article/1237](http://www.linuxjournal.com/article/1237)

$ head a/\* b/\*  
==\> a/bar \<==  
bar

==\> a/foo \<==  
foo

==\> b/bar \<==  
foo

==\> b/foo \<==  
bar

$ diff -u a b  
diff -u a/bar b/bar

- — a/bar 2006-05-29 05:08:11.000000000 -0700  
+++ b/bar 2006-05-29 05:08:16.000000000 -0700  
@@ -1 +1 @@
- -bar  
+foo  
diff -u a/foo b/foo
- — a/foo 2006-05-29 05:07:49.000000000 -0700  
+++ b/foo 2006-05-29 05:08:05.000000000 -0700  
@@ -1 +1 @@
- -foo  
+bar  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFEeuUYmV9O7RYnKMcRAvw6AKCygIWiiPpworeAI5HRaf8euu1f6QCePKRQ  
pwYlDR5ANIy4Uk6f1797LLo=  
=Mlsd  
-----END PGP SIGNATURE-----
