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

Re: Set difference between sets of files



On Tue, 5 May 2009 19:36:49 +0300
Itai Fiat <itai.fiat@xxxxxxxxx> wrote:
> I would like to compute the set difference between two sets of files -
> that is, obtain a list of files found in one set and not in the other.
> 
> For instance, say I have two directories - master/ and backup/ - containing
> (mostly) identical files. I would like to remove from backup/ all files which
> have been removed from master/. I would like to achieve this by doing
> something like this:
> 
>     cd master/
>     MASTER_FILES=(**/*(.))
>     cd ../backup
>     BACKUP_FILES=(**/*(.))
>     TO_REMOVE=<set difference between BACKUP_FILES and MASTER_FILES>
>     rm -f $TO_REMOVE
> 
> 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?

One way of doing it is to turn the backup files into the pattern of a set
of alternatives, by joining together with a "|", and then excluding the
matched pattern from the master files using the ":#" parameter operator.

% master_files=(foo bar "funny name" stuff random)
% backup_files=(foo bar "funny name")
% eval print -lr -- '${master_files:#'"("${(j.|.)${(q)backup_files}}")"'}'
stuff
random

I deliberately tried this with a difficult character in the pattern
(actually, I think space would have worked without quoting, but the "(q)"
does quote it, so it should work here like any character that does need
quoting), which is why I ended up with an "eval"; using the GLOB_SUBST
option didn't seem to handle quoting well.

It might be useful to have a special expression for excluding anything that
matches an element of a given array, but there isn't one.

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



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