Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Set difference between sets of files

On Tue, 5 May 2009, Phil Pennock wrote:

> On 2009-05-05 at 19:36 +0300, Itai Fiat wrote:
> > I know that this can be done by writing both sets to temporary files, 
> > sorting them, and using the standard Unix command "comm", but is there 
> > an elegant way to do this from within Zsh?
> I do set operations using the functions I posted in:
>   http://www.zsh.org/mla/workers/2008/msg01422.html
> which is zsh-workers 25763.
> With those, you need a recent zsh release, since it uses new syntax
> added by Peter in September last year.  zsh 4.3.7 or newer will be fine.
> Then I use newset to declare a "set", implemented in zsh as an
> auto-unique array, and the other functions in there to perform set
> arithmetic.  I routinely use these functions to manipulate sets of
> a couple thousand items, adding and removing and intersecting, etc, to
> carry out my work.  It works for me and I got busy shortly thereafter so
> I haven't come up with anything nicer.
> -Phil

Am I missing something, or isn't this the canonical case for using 
associative arrays?

e.g., the first thing that came to mind:

[0]$ find master backup

master/foo bar baz


[1]$ diff -ur =(cd master ; ls) =(cd backup ; ls)
--- /tmp/zshotlEqg      2009-05-06 00:15:05.984375000 -0400
+++ /tmp/zshEysrph      2009-05-06 00:15:06.062500000 -0400
@@ -1,3 +1,4 @@
-foo bar baz

[2]$ MASTER=( master/**/*(.:s.master/.) )
[3]$ BACKUP=( backup/**/*(.:s.backup/.) )
[4]$ typeset -A _master
[5]$ for l in $MASTER ; _master[$l]=true
[6]$ REMOVE=() ; for l in $BACKUP ; [ -z $_master[$l] ] && REMOVE+=($l)
[7]$ print -r rm $REMOVE
rm !@#%$@% another@thing

There's probably even a better way to write the line marked [4], too.

Messages sorted by: Reverse Date, Date, Thread, Author