tar command has a way to list the contents of an archive. The short form for this is
tar -tf archive.tar.
By using this together with
grep, and command substitution, you get the following:
rm -f $(find . -d | head -n -1 | grep -Fv "$(tar -tf archive.tar)")
Run this in the directory where you want the contents of the archive, and replace
archive.tar with the path to the archive file.
Working from right to left for the pipeline inside the outermost command substitution:
find . -d: Lists all the files and directories under the current directory, listing them in depth-first order. The depth-first ordering is important here, as we plan to use this file list for deletions and therefore must delete directory contents before deleting directories themselves.
head -n -1: Exclude the last line from the
find command. This will remove the entry for
/path itself, which may or may not be present in the archive. If we weren't doing things in depth-first order, this would instead be
tail -n -1.
grep -Fv "$(tar -tf archive.tar)": Pass the listing of the archive to a grep command, which will then filter out those lines from the list returned by
find, so only the files which aren't' in the archive will be passed to the outter
A couple of notes:
- This probably isn't quite POSIX compliant. It should work in GNU bash though.
- This is dependent on how tar reports the archive contents and how the archive was created. In particular, the listing has to match up with how
find reports things. With GNU tar and most archives, it should work. If it doesn't for your case, you can probably get it to work by using either
awk on the output of the tar command inside the innermost command substitution.
- Make sure and test this before using it on production data, if it doesn't work for either of the two above reasons, it's liable to remove everything form the directory you run it in.