Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Set difference between sets of files
- X-seq: zsh-users 14091
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-users@xxxxxxxxxx
- Subject: Re: Set difference between sets of files
- Date: Tue, 05 May 2009 11:00:10 -0700
- In-reply-to: <20090505175739.7b2e4aca@news01>
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- References: <94de1b620905050936g442490e4t3da42ac3946cb29@xxxxxxxxxxxxxx> <20090505175739.7b2e4aca@news01>
On May 5, 5:57pm, Peter Stephenson wrote:
}
} > 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'd typically do this like so:
rm $(for f in backup/**/*(.); [[ -e ${f:s@backup/@master/} ]] || print $f)
Of course that needs a bit of cleanup if any of the file names might have
spaces in them.
Another way is this:
cd backup
rm -f **/*(.e:'[[ ! -f ../master/$REPLY ]]':)
Neither of these uses set-differencing on arrays; sometimes you have to
think about alternate approaches to the original problem.
} 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.
Here's another way:
typeset -A differ
eval differ\[${(q)^MASTER_FILES}\]=a
eval differ\[${(q)^BACKUP_FILES}\]=b
print -l -- ${(k)differ[(R)a]}
I tried using
eval noglob unset differ\[${(q)^BACKUP_FILES}\]
but that failed on names containing spaces, for some reason.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author