![列出 backup2.tar.bz2 中存在但 backup1.tar.bz2 中不存在的所有文件](https://linux22.com/image/163187/%E5%88%97%E5%87%BA%20backup2.tar.bz2%20%E4%B8%AD%E5%AD%98%E5%9C%A8%E4%BD%86%20backup1.tar.bz2%20%E4%B8%AD%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%9A%84%E6%89%80%E6%9C%89%E6%96%87%E4%BB%B6.png)
这列出了两个备份中的所有文件,按大小排序:
tar tvf backup1.tar.bz2 |sort -k3 -n >backup1_files.txt
tar tvf backup2.tar.bz2 |sort -k3 -n >backup2_files.txt
我想列出backup2.tar.bz2 中存在但 backup1.tar.bz2 中不存在的所有文件,按大小排序。
这个怎么做?
注意:
做一个
diff
这些 .txt 文件是行不通的,因为某些文件的修改日期不相同。因此这个问题不是重复的有没有一种工具可以获取一个文件中不在另一个文件中的行?。删除
v
会删除修改日期,还会删除文件大小,因此这不是一个选项,因为无法按大小对它们进行排序。
答案1
如果您有 AWK,则可以使用如下所示的单行代码:
awk '{if (NR==FNR) { arr[$6]=1 } else { if (! arr[$6]) { print } } }' backup2_files.txt backup1_files.txt
这将使用备份 2 的文件名构建一个 AWK 数组,然后检查该数组中是否存在备份 1 的文件名。如果没有,它将打印它们。
编辑:这是一个改进的版本,对于名称中带有空格的文件更加健壮,并且不需要任何临时文件:
awk '{ key=""; for (i = 6; i <= NF; i++) { key=col_cat $i }; if (NR == FNR) { arr[key]=1 } else { if (! arr[key]) { print } } }' <(tar tvf backup2.tar.bz2 |sort -k3 -n) <(tar tvf backup1.tar.bz2 |sort -k3 -n)
您可以将 awk 代码写入文件中intersect.awk
,然后像这样重复使用它:
awk -f intersect.awk <(tar tvf backup2.tar.bz2 |sort -k3 -n) <(tar tvf backup1.tar.bz2 |sort -k3 -n)
答案2
其他答案中提出的方法不起作用,因为 tar 将打印:
name123 symbolic link to namexyz
存档中是否有符号链接以及硬链接的类似消息。
所以处理这个问题的唯一方法是使用star
:
star -t -tpath < archive.tar.bz2 > somename
对所有档案执行此操作,对输出进行排序,然后使用众所周知的方法来比较结果文件。
该选项-tpath
指示star
仅在一行上打印一次文件名。
star
是 的一部分schilytools
。
顺便说一句:如果文件名包含换行符,此方法会使比较工具感到困惑。