从 jar 文件中提取文件并获取差异

从 jar 文件中提取文件并获取差异

在现实世界中,我在各个版本的 jar 文件中有一个 xsd 我试图检查 xsd 是否在版本 10.xyz 到 11.abc 之间发生了变化

我有不同的发布目录,这些目录是只读的,如下所示,在某些 /m/n/i/10.xyz 或 11.xyz 中我想搜索 abc.jar ,它可以埋在我的发布目录 10.xyz 或 11.xyz 中在所有这些版本的某些 p/q/r/abc.jar 中,并从中提取 xyz.xsd 并在它们之间进行比较?而且我没有对版本目录的写入权限。

我怎样才能在Unix或shell脚本中实现它?我是 Unix 新手。目录结构

.
|-- 10.1.2.2.0
|   `-- GENERIC
|       `-- RELEASE
          --  x/y/z/abc.jar
|-- 10.1.2.3.0
|   `-- GENERIC
|       `-- RELEASE
          -- x/y/z/abc.jar
|-- 10.1.3.1.0
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.3.0
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.3.0-HOTPLUG
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.3.0BPA
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.3.0WEBSPHERE
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.3.1
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR1
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR10
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR2
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR3
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR4
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR5
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR6
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR7
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR8
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.4.0MLR9
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.5.0
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.5.0.QA.06012009
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.5.1
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.5.2
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3.5.3
|   `-- GENERIC
|       `-- RELEASE
|-- 10.1.3QAMLR6
|   `-- GENERIC
|       `-- RELEASE
|-- 11.1.1.1.0
|   `-- GENERIC
|       `-- RELEASE
|-- 11.1.1.1.0.BPA
|   `-- GENERIC
|       `-- RELEASE
|-- 11.1.1.1.0.CEP
|   `-- GENERIC
|       `-- RELEASE
|-- 11.1.1.2.0
|   `-- GENERIC
|       `-- RELEASE
|-- 11.1.1.3.0
|   `-- GENERIC
|       `-- RELEASE
`-- 11.1.1.4.0
    `-- GENERIC
        `-- RELEASE

93 directories, 0 files

答案1

abc.jar假设每个目录下 只有一个:

basedir=path_to_your_Release_dirs
mkdir /var/tmp/reldiff
cd /var/tmp/reldiff
for x in Release1 Release2 Release3; do
   mkdir $x
   cd $x
   find $basedir/$x -name abc.jar -print0 | xargs -0 unzip -j xyz.xsd
   cd ..
done
diff3 */xyz.xsd

答案2

也许是这样的?

#!/bin/sh

number_of_releases = 3    

for i in $(seq 1 $number_of_releases)
do
cd Release$i
jar xf abc.jar xyz.xsd
mv xyz.xsd ../xyz.xsd_$i
cd ..
done

for i in $(seq 1 $(($number_of_releases-1)))
do
diff xyz.xsd_$i xyz.xsd_$(($i+1)) > diff_Release$(($i))_to_Release$(($i + 1))
done

编辑 请参阅@rany-albeg-wein 评论

答案3

该脚本应该可以满足您的需要。它做出了几个假设,并且没有过度模块化。也没有任何检查。需要更多细节才能使其更加稳健。

find . -type f -name 'abc.jar' -exec sh -c '
num=$(echo {} | sed 's#.*Release##' | sed 's#/.*##')
jar xvf {} xyz.xsd
mv xyz.xsd xyz.xsd.${num}
' {} \;

for i in xyz.xsd*; do 
  currnum=$(echo $i | sed 's#xyz.xsd.##')
  let nexnum=currnum+1
  [ ! -f xyz.xsd${nexnum} ] || exit
  echo "diff $i xyz.xsd${nexnum} > diffs_xyz.xsd_${currnum}_${nexnum}.txt"
done

样本数据

$ tree -A
.
├── myscript.bash
├── Release1
│   ├── abc.jar
│   └── xyz.jar
├── Release2
│   ├── abc.jar
│   └── xyz.jar
├── Release3
│   ├── abc.jar
│   └── xyz.jar
└── Release43
    └── xyz.jar

4 directories, 8 files

答案4

您可以使用此功能从 jar 中提取所有文件

find /path/to/dir1 /path/to/dir2 -type f -name 'abc.jar' -exec bash -c 'jar xf "$1" "$2"' _ {} /path/to/file/inside/jar \;

正如您所看到的,jar可以采用第二个(以及 on )参数,后面xf将是您要从 jar 文件中提取的文件的名称。该路径在 jar 树结构中必须是绝对路径。如果您不知道 jar 文件中文件的路径,可以使用此命令,该命令将提取整个 jar 文件:

find /path/to/dir1 /path/to/dir2 -type f -name 'abc.jar' -exec bash -c 'jar xf "$1"' _ {} \;

如果您使用第一种方法,那么您可以像这样迭代 xsd 文件:

for i in *.xsd; do
    # diff your files here
done

如果你使用第二个,你将不得不使用这样的东西:

while IFS= read -rd $'\0' xsd; do
    # diff your files here
done < <(find /path/to/relevant/location -type f -name '*.xsd' -print0)

相关内容