Gibt es ein Namensanalyse-Tool, das Teil des offiziellen RPM-Tool-Pakets ist?
Ich habe eine Liste mit Dateinamen. Jeder ist der Dateiname eines RPM-Pakets. Ich habe nicht die tatsächlichen Pakete, nur die Dateinamen. Für jedes muss ich den Paketnamen und die Version ($ NAME und $ VERSION) extrahieren. Der Grund, warum ich das brauche, ist, dass ich ein Skript schreibe, das dann sicherstellt, dass "yum install $ VERSION" $ VERSION installiert. Dies ist Teil eines Systems, das Pakete erstellt und überprüft, ob sie ordnungsgemäß hochgeladen wurden.
Die Liste der Dateinamen sieht folgendermaßen aus:
$ cat /tmp/packages.txt
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-el-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/mercurial-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/mercurial-hgk-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/python-redis-2.8.0-2.el6.noarch.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/redis-2.6.16-1.el6.1.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
Ich fand den folgenden Code, der eine BASH-Funktion ist, die die Aufgabe erledigt:
function parse_rpm() { RPM=$1;B=${RPM##*/};B=${B%.rpm};A=${B##*.};B=${B%.*};R=${B##*-};B=${B%-*};V=${B##*-};B=${B%-*};N=$B;echo "$N $V $R $A"; }
for i in $(</tmp/packages.txt) ; do
parse_rpm $i
done
Es klappt. Meistens. Es gibt einige Ausnahmen:
$ parse_rpm CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
sei_dnsmaster 1.0 99.el6 x86_64
Beachten Sie, dass es nicht die richtige Version bekommen hat (es sollte 1.0-99 sein)
Ich frage mich (1), ob das rpmdev-Paket ein Tool enthält, das dies korrekt ausführt. (2) Wenn nicht, gibt es einen offiziellen regulären Ausdruck, den ich verwenden könnte. (3) Was ist das Python-Äquivalent zu diesem Regex?
Danke im Voraus!
Antworten:
Sie müssen nichts davon tun. RPM verfügt über ein Abfrageformatargument, mit dem Sie genau die Daten angeben können, die Sie empfangen möchten. Es wird sogar ohne Zeilenende ausgegeben, wenn Sie diese nicht angeben.
Zum Beispiel:
Die vollständige Liste der Variablen, die Sie verwenden können, erhalten Sie mit:
Beachten Sie, dass in diesem Fall eine
RELEASE
Ausgabe wie84.el6
normal ist und erwartet wird, da RPM-Pakete auf diese Weise versioniert werden, wenn sie von oder für eine Distribution gepackt werden.quelle
$ rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}" -q CentOS/6/x86_64/sei_dnsmaster-1.0-84.el6.x86_64.rpm package CentOS/6/x86_64/sei_dnsmaster-1.0-84.el6.x86_64.rpm is not installed
libopenssl0_9_8-32bit-0.9.8j-0.26.1_0.50.1.x86_64.delta.rpm
Mir wurde gesagt, dass der offizielle Weg, was ich suche, in Python ist:
Ich habe ein kurzes Python-Programm geschrieben, das genau das tut, was ich brauche. Ich werde das Skript dem rpmdev-Projekt zur Aufnahme anbieten.
quelle
Ich habe reguläre Ausdrücke ausgearbeitet, die zu allen Daten passen, mit denen ich sie testen konnte. Ich musste eine Mischung aus gierigen und nicht gierigen Streichhölzern verwenden. Das heißt, hier ist meine Perl- und Python-Versionen:
Perl:
Python:
Ich hätte lieber einen regulären Ausdruck, der aus dem RPM-Projekt stammt. Das, was ich oben erfunden habe, muss fürs Erste tun.
quelle
.*
Sie es, es sei denn, Sie möchten WIRKLICH mit etwas übereinstimmen). Schön zu sehen, dass du es selbst gefunden hast!AdbeRdr9.5.5-1_i486linux_enu.rpm
), der Ihre Regex-Analyse oben bricht.RPM-Dateien können in extremen Fällen einige unkonventionelle Dateinamen haben, aber im Allgemeinen können Sie den NVR auf die Bindestriche aufteilen. Der Haken ist, dass der N (Name) -Teil des NVR möglicherweise Bindestriche und Unterstriche enthält, aber V (Version) und R (Release) haben garantiert keine überflüssigen Bindestriche. Sie können also zunächst den VR-Teil abschneiden, um einen Namen abzuleiten.
Darauf aufbauend können Sie den Version- und Release-Teil isolieren.
Teilen Sie einfach den Bindestrich erneut, um den gewünschten Teil zu isolieren. Und säubern Sie offensichtlich die vorgegebenen Zeichenfolgen für arch und rpm-Dateierweiterungen. Ich gebe Ihnen nur eine Vorstellung davon, wie es in bash angegangen werden könnte.
quelle
Verwenden Sie die Optionen -q --queryformat von rpm wie oben beschrieben. Wenn Sie dies für ein nicht installiertes Paket tun möchten, können Sie die rpm mit der folgenden
-p
Option angeben :z.B
gibt mir
Es ist also falsch, nur den Dateinamen zu teilen!
so achtet , dann ist dies die Drehzahl nicht die richtigen Details, zum Beispiel
1.fedora
ist eigentlich1.fc10
in der Drehzahl.quelle
Wenn Sie mit regulären Ausdrücken und / oder Perl vertraut sind, ist das ganz einfach.
oder der Regex alleine:
Wenn Sie es teilen, ist das:
[^\-]+
(Escapezeichen, da Bindestrich in Zeichengruppen eine besondere Bedeutung hat)[^\-]+?
([^\-]+?)
([^\-]+?)-
.rpm
):([^\-]+?)-(.*).rpm$
(der Dollar bedeutet "Zeilenende")m#([^\-]+?)-(.*).rpm$#
Getan ! Holen Sie sich einfach beide Teile in den Variablen
$1
und$2
Kommentar zum ersten Einzeiler:
Ich war in einem Verzeichnis mit vielen RPM-Dateien, daher die
ls
.perl -p
ist äquivalent zu ;Dies erklärt, dass ich eine Null-Zeichenfolge
$_
eingeben musste, um zu vermeiden, dass Perl die Zeile nach dem Extrahieren und benutzerdefinierten Drucken zurückdruckt. Beachten Sie, dass ich Substitutionen hätte verwenden können, um diesen kleinen "Hack" zu vermeiden.quelle
module-init-tools-3.9-21.el6_4.x86_64.rpm
.Meiner Meinung nach ist die einfachste Art der Shell:
Das heißt: Kehre jede Zeile um, indem du nur den ersten Teil ( Emanelif ) mit einem Schrägstrich schneidest , dann mit einem Bindestrich alle Teile bis auf die ersten beiden (dh hinterlasse ESAELER einschließlich Emanelif Ethfilter und NOISREV ) und kehre das Enil zurück.
Mit Ihrer Beispieldatei:
Um andere Teile zu bekommen, lesen Sie bitte den Schnitt (1) .
quelle
Sie können nutzen
dnf info
. Hier ist ein Bash-Beispielskript, um Werte abzurufen und als Variable festzulegen:Es wird ein Ergebnis angezeigt, auch wenn das Paket nicht installiert ist.
quelle