Czy istnieje narzędzie do analizy nazw, które jest częścią oficjalnego pakietu narzędzi RPM?
Mam listę nazw plików. Każda to nazwa pliku pakietu RPM. Nie mam rzeczywistych pakietów, tylko nazwy plików. Dla każdego muszę wyodrębnić nazwę i wersję pakietu ($ NAME i $ VERSION). Potrzebuję tego, dlatego, że piszę skrypt, który następnie upewnia się, że „yum install $ VERSION” instaluje $ VERSION. Jest to część systemu, który buduje pakiety i sprawdza, czy zostały poprawnie przesłane.
Lista nazw plików wygląda następująco:
$ 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
Znalazłem następujący kod, który jest funkcją BASH wykonującą zadanie:
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
To działa. Przeważnie. Istnieją pewne wyjątki:
$ parse_rpm CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
sei_dnsmaster 1.0 99.el6 x86_64
Zauważ, że wersja nie otrzymała poprawnie (powinna być 1.0-99)
Zastanawiam się (1), czy w pakiecie rpmdev znajduje się narzędzie, które robi to poprawnie. (2) Jeśli nie, czy istnieje oficjalne wyrażenie, którego mógłbym użyć. (3) Jaki jest odpowiednik tego wyrażenia regularnego w Pythonie?
Z góry dziękuję!
Odpowiedzi:
Nie musisz tego robić; RPM ma argument formatu zapytania, który pozwala dokładnie określić dane, które chcesz otrzymać. Wyprowadzi nawet bez zakończeń linii, jeśli ich nie określisz.
Na przykład:
Pełną listę zmiennych, których można użyć, można uzyskać za pomocą:
Zauważ, że w przypadku
RELEASE
wyjścia typu like84.el6
jest normalne i oczekiwane, ponieważ tak właśnie są wersje pakietów RPM, gdy są pakowane przez lub dla dystrybucji.źródło
$ 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
Powiedziano mi, że oficjalnym sposobem robienia tego, czego szukam, jest Python:
Napisałem krótki program w języku Python, który robi to, czego potrzebuję. Oferuję skrypt do projektu rpmdev w celu włączenia.
źródło
Opracowałem wyrażenia regularne, które pasują do wszystkich danych, z którymi mogłem je przetestować. Musiałem użyć mieszanki chciwych i niechcianych zapałek. To powiedziawszy, oto moje wersje Perla i Pythona:
Perl:
Pyton:
Wolę mieć wyrażenie regularne, które pochodzi z projektu RPM. Ten, który wymyśliłem powyżej, będzie musiał zrobić na razie.
źródło
.*
chyba że NAPRAWDĘ chcesz coś dopasować). Miło widzieć, że znalazłeś sam!AdbeRdr9.5.5-1_i486linux_enu.rpm
), który łamie twoją analizę wyrażeń regularnych powyżej.Pliki Rpm mogą mieć w niektórych przypadkach nazwy funky, ale ogólnie można podzielić NVR na łączniki. Haczyk to część N (nazwa) NVR może zawierać łączniki i znaki podkreślenia, ale gwarantuje się, że V (wersja) i R (wydanie) nie będą miały żadnych łączników zewnętrznych. Możesz więc zacząć od przycięcia części VR, aby uzyskać nazwę.
Na tej podstawie możesz wyizolować część Wersja i wydanie.
Po prostu ponownie podziel łącznik, aby wyizolować potrzebną część. I oczywiście oczyść ciągi rozszerzeń plików arch i rpm, co jest dane. Po prostu daje wyobrażenie o tym, jak można do tego podejść w bash.
źródło
Użyj opcji -q --queryformat z rpm, jak powiedziano wcześniej, jeśli chcesz to zrobić w niezainstalowanym pakiecie, możesz określić rpm za pomocą
-p
opcji, jak poniżej:na przykład
daje mi
więc dzielenie nazwy pliku jest nieprawidłowe!
więc zwróć uwagę , to nie są prawidłowe szczegóły rpm, np.
1.fedora
faktycznie jest1.fc10
w rpm.źródło
Jeśli znasz Wyrażenia regularne i / lub Perl, to całkiem proste.
lub sam regex:
Jeśli podzielisz to:
[^\-]+
łącznik , przynajmniej jedna postać: (ucieka, ponieważ łącznik ma specjalne znaczenie w grupach znaków)[^\-]+?
([^\-]+?)
([^\-]+?)-
.rpm
):([^\-]+?)-(.*).rpm$
(dolar oznacza „koniec linii”)m#([^\-]+?)-(.*).rpm$#
Gotowy ! Po prostu weź obie części do zmiennych
$1
i$2
Komentarz do pierwszego linijki:
Byłem w katalogu z wieloma plikami rpm, stąd
ls
.perl -p
jest równa ;Które wyjaśniają, że musiałem wstawić łańcuch zerowy,
$_
aby uniknąć drukowania przez Perla linii po wyodrębnieniu i wydrukowaniu na zamówienie. Zwróć uwagę, że mogłem użyć substytucji, aby uniknąć tego małego „hacka”.źródło
module-init-tools-3.9-21.el6_4.x86_64.rpm
.IMHO najprostszym sposobem powłoki jest:
To znaczy: odwróć każdą linię, używając cięcia przecinającego tylko pierwszą część ( emanelif ), a następnie za pomocą cięcia łącznikiem wszystkie oprócz pierwszych dwóch części (tj. Zostaw ESAELER włącznie z emanelif et foserser i NOISREV ) i odwróć enil z powrotem.
Z twoim przykładowym plikiem:
Aby zdobyć inne części, należy poćwiczyć na czytaniu cięcia (1) .
źródło
Możesz wykorzystać
dnf info
. Oto przykładowy skrypt Bash, aby uzyskać wartości i ustawić jako zmienną:Daje wynik, nawet jeśli pakiet nie jest zainstalowany.
źródło