How to compare the content of a tarball with a folder

How can I compare a tar file (already compressed) of the original folder with the original folder?

First I created archive file using

tar -kzcvf directory_name.zip directory_name

Then I tried to compare using

tar -diff -vf directory_name.zip directory_name

But it didn't work.

0

6 Answers

--compare (-d) is more handy for that.

tar --compare --file=archive-file.tar

works if archive-file.tar is in the directory it was created. To compare archive-file.tar against a remote target (eg if you have moved archive-file.tar to /some/where/) use the -C parameter:

tar --compare --file=archive-file.tar -C /some/where/

If you want to see tar working, use -v without -v only errors (missing files/folders) are reported.

Tipp: This works with compressed tar.gz archives, too.

3

It should be --diff

Try this (without the last directory_name):

tar --diff -vf directory_name.zip

The problem is that the --diff command only looks for differences on the existing files among the tar file and the folder. So, if a new file is added to the folder, the diff command does not report this.

1

The method of pix is way slow for large compressed tar files, because it extracts each file individually. I use the tar --diff method loking for files with different modification time and extract and diff only these. The files are extracted into a folder base.orig where base is either the top level folder of the tar file or teh given comparison folder. This results in diffs including the date of the original file.

Here is the script:

#!/bin/bash
set -o nounset
# Print usage
if [ "$#" -lt 1 ] ; then echo 'Diff a tar (or compressed tar) file with a folder' echo 'difftar-folder.sh <tarfile> [<folder>] [strip]' echo default for folder is . echo default for strip is 0. echo 'strip must be 0 or 1.' exit 1
fi
# Parse parameters
tarfile=$1
if [ "$#" -ge 2 ] ; then folder=$2
else folder=.
fi
if [ "$#" -ge 3 ] ; then strip=$3
else strip=0
fi
# Get path prefix if --strip is used
if [ "$strip" -gt 0 ] ; then prefix=`tar -t -f $tarfile | head -1`
else prefix=
fi
# Original folder
if [ "$strip" -gt 0 ] ; then orig=${prefix%/}.orig
elif [ "$folder" = "." ] ; then orig=${tarfile##*/} orig=./${orig%%.tar*}.orig
elif [ "$folder" = "" ] ; then orig=${tarfile##*/} orig=${orig%%.tar*}.orig
else orig=$folder.orig
fi
echo $orig
mkdir -p "$orig"
# Make sure tar uses english output (for Mod time differs)
export LC_ALL=C
# Search all files with a deviating modification time using tar --diff
tar --diff -a -f "$tarfile" --strip $strip --directory "$folder" | grep "Mod time differs" | while read -r file ; do # Substitute ': Mod time differs' with nothing file=${file/: Mod time differs/} # Check if file exists if [ -f "$folder/$file" ] ; then # Extract original file tar -x -a -f "$tarfile" --strip $strip --directory "$orig" "$prefix$file" # Compute diff diff -u "$orig/$file" "$folder/$file" fi
done

I recently needed a better compare than what "tar --diff" produced so I made this short script:

#!/bin/bash
tar tf "$1" | while read ; do if [ "${REPLY%/}" = "$REPLY" ] ; then tar xOf "$1" "$REPLY" | diff -u - "$REPLY" fi
done
1

To ignore differences in some or all of the metadata (user, time, permissions), you can pipe the result to awk:

tar --compare --file=archive-file.tar -C /some/where/ | awk '!/Mode/ && !/Uid/ && !/Gid/ && !/time/'

That should output only the true differences between the tar and the directory /some/where/

The easy way is to write:

  • tar df file This compares the file with the current working directory, and tell us about if any of the files has been removed.
  • tar df file -C path/folder This compares the file with the folder.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like