如何比较tarball文件和文件夹的内容

38

如何比较已经压缩的tar文件与原始文件夹?

首先使用以下命令创建归档文件:

tar -kzcvf directory_name.zip directory_name

接着我尝试使用比较

tar -diff -vf directory_name.zip directory_name

但它没有起作用。


尝试使用“-d”选项而不是“-diff”。在您的情况下使用“-dvf”。 - Sathesh
7个回答

57

--compare (-d)对此更加方便。

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

如果archive-file.tar在创建时的目录中,该命令会正常工作。要将archive-file.tar与远程目标(例如,如果您将archive-file.tar移动到/some/where/)进行比较,请使用-C参数:

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

如果您想看到tar的工作情况,请使用-v,而不使用-v只会报告错误(缺少文件/文件夹)。

提示:这也适用于压缩的tar.bz/tar.gz档案。


1
这是答案,它回答了一个更普遍和重要的问题:“如何比较tarball的内容与文件夹”,这个问题更为普遍,包括了这个问题。因此,我认为问题应该重新表述,并接受这个答案。 - Simon C.
10
顺便问一下,你知道如何消除GID和UID的比较吗? - Simon C.
3
无论我尝试哪种方式,都会出现“警告:无法获取状态:没有这个文件或目录”的提示。 - Arkham Angel

12

应该使用--diff选项

尝试这个命令(去掉最后的directory_name):

tar --diff -vf directory_name.zip
问题在于--diff命令只会查找tar文件和文件夹中现有文件之间的差异。因此,如果向文件夹中添加了新文件,则diff命令不会报告此变化。

问题在于--diff命令只会查找tar文件和文件夹中现有文件之间的差异。因此,如果向文件夹中添加了新文件,则diff命令不会报告此变化。


这个命令是否报告文件元数据的差异,例如所有权、权限、符号链接目标、设备节点属性等?我正在计划备份 Linux 根文件系统,并希望确保所有这些元数据都是正确的。 - enigmaticPhysicist

6
为忽略某些或全部元数据(用户、时间、权限)的差异,您可以将结果通过管道传递给awk命令:
tar --compare --file=archive-file.tar -C /some/where/ | awk '!/Mode/ && !/Uid/ && !/Gid/ && !/time/'

这应该仅输出tar和目录/some/where/之间的真实差异。


4

对于大型压缩的tar文件,使用pix方法会非常慢,因为它会单独提取每个文件。我使用tar --diff方法查找修改时间不同的文件,并仅提取和比较这些文件。这些文件被提取到一个名为base.orig的文件夹中,其中base是tar文件的顶层文件夹或给定的比较文件夹。这样可以得到包括原始文件日期的差异。

以下是脚本:

#!/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

1

最近我需要比“tar --diff”生成的更好的比较工具,所以我写了这个简短的脚本:

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

@staticx $REPLY是由read命令(在while测试中)创建的。它包含了完整的行,所以在这种情况下,它是来自tar t命令的当前文件名。 - pix

0

您可以使用diff的--compare(-diff,d)选项。

您需要注意,因为diff仅比较在命令行上指定的文件,并且仅比较同时存在于存档中的文件。例如,不会报告新存在的文件。

通常,我更喜欢采用pix的方法来获得更多控制权。

然而,与pix和Michael Soegtrop不同,我认为您不必提取任何文件。

以下代码测试diff比较文件的能力。

touch refF; setTM12 () { touch -r refF F1 F2; };

# create the files
echo a1a > F1; echo a2a > F2; echo a3a>F3; echo a4a>F4; setTM12;

tar cf tarF F1 F2 F3 F4;

# do not change times of F1 F2
# modify F1 F2 F3, change the mtime of F4
echo mod > F1; echo longer > F2; setTM12;
sleep 2; echo XXX > F3; touch F4;

tar -df tarF F1 F2 F3 F4

F1: Contents differ
F2: Size differs
F3: Mod time differs
F3: Contents differ
F4: Mod time differs

你可能需要知道,Size differs 隐含地标记了内容不同的文件,例如 F2-v 是一个方便的选项,也有两个作用。
tar -vdf tarF F1 F2 F3 F4
F1
F1: Contents differ
F2
F2: Size differs          <--- Means that the Contents differ, too !
F3
F3: Mod time differs
F3: Contents differ
F4
F4: Mod time differs

-1

简单的方法是写:

  • tar df file 这将比较 file 和当前工作目录,并告诉我们是否有任何文件已被删除。
  • tar df file -C path/folder 这将比较文件和文件夹。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接