Extrahieren Sie eine Datei aus einer JAR-Datei und erhalten Sie den Diff

Extrahieren Sie eine Datei aus einer JAR-Datei und erhalten Sie den Diff

In der realen Welt habe ich eine XSD in einer JAR-Datei über verschiedene Releases hinweg. Ich versuche zu prüfen, ob sich die XSD zwischen den Releases 10.xyz und 11.abc geändert hat.

Ich habe verschiedene Release-Verzeichnisse, die schreibgeschützt sind, wie unten in einigen /m/n/i/10.xyz oder 11.xyz. Ich möchte in allen diesen Releases nach abc.jar suchen, das in meinem Release-Verzeichnis 10.xyz oder 11.xyz in einigen p/q/r/abc.jar vergraben sein kann, und xyz.xsd daraus extrahieren und einen Diff zwischen ihnen durchführen? Außerdem habe ich keine Schreibberechtigung für die Release-Verzeichnisse.

Wie kann ich das in Unix oder Shell-Skript erreichen? Ich bin neu bei Unix. Verzeichnisstruktur

.
|-- 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

Antwort1

Angenommen, es gibt nur eines abc.jarin jedem Verzeichnis:

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

Antwort2

So etwas in der Art vielleicht?

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

BEARBEITEN siehe Kommentar von @rany-albeg-wein

Antwort3

Dieses Skript sollte tun, was Sie brauchen. Es macht mehrere Annahmen und ist nicht übermäßig modular. Es hat auch keine Prüfungen. Es bräuchte mehr Einzelheiten, um es robuster zu machen.

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

Beispieldaten

$ 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

Antwort4

Mit dieser Funktion können Sie alle Dateien aus Ihren Jars extrahieren

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

Wie Sie sehen, jarkann ein zweites ( und ein ) Argument verwendet werden, nach xfdem der Name der Datei folgt, die Sie aus der JAR-Datei extrahieren möchten. Dieser Pfad muss innerhalb Ihrer JAR-Baumstruktur absolut sein. Wenn Sie den Pfad zur Datei innerhalb der JAR-Datei nicht kennen, können Sie diesen Befehl verwenden, der stattdessen die gesamte JAR-Datei extrahiert:

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

Wenn Sie die erste Methode verwendet haben, können Sie Ihre XSD-Dateien einfach wie folgt durchlaufen:

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

Wenn Sie die zweite Option verwenden, müssen Sie etwa Folgendes verwenden:

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

verwandte Informationen