Apakah ada alat parsing nama yang merupakan bagian dari paket alat RPM resmi?
Saya memiliki daftar nama file. Masing-masing adalah nama file dari paket RPM. Saya tidak memiliki paket yang sebenarnya, hanya nama file. Untuk setiap saya perlu mengekstrak nama dan versi paket ($ NAME dan $ VERSION). Alasan saya membutuhkan ini adalah saya menulis skrip yang kemudian memastikan bahwa "yum install $ VERSION" menginstal $ VERSION. Ini adalah bagian dari sistem yang membuat paket dan memverifikasi mereka diunggah dengan benar.
Daftar nama file terlihat seperti:
$ 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
Saya menemukan kode berikut yang merupakan fungsi BASH yang melakukan tugas:
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
Berhasil. Kebanyakan. Ada beberapa pengecualian:
$ parse_rpm CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
sei_dnsmaster 1.0 99.el6 x86_64
Perhatikan bahwa itu tidak mendapatkan versi dengan benar (seharusnya 1,0-99)
Saya bertanya-tanya (1) apakah ada alat dalam paket rpmdev yang melakukan ini dengan benar. (2) Jika tidak, apakah ada regex resmi yang bisa saya gunakan. (3) Berapakah python yang setara dengan regex itu?
Terima kasih sebelumnya!
Jawaban:
Anda tidak perlu melakukan semua ini; RPM memiliki argumen format kueri yang akan memungkinkan Anda menentukan dengan tepat data yang ingin Anda terima. Bahkan akan menghasilkan tanpa akhir baris jika Anda tidak menentukannya.
Contohnya:
Daftar lengkap variabel yang dapat Anda gunakan dapat diperoleh dengan:
Perhatikan bahwa dalam kasus
RELEASE
, output seperti84.el6
adalah normal dan diharapkan, karena ini sebenarnya bagaimana paket RPM diversi ketika dikemas oleh atau untuk distribusi.sumber
$ 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
Saya telah diberi tahu cara resmi untuk melakukan apa yang saya cari adalah dengan Python:
Saya telah menulis program Python pendek yang melakukan apa yang saya butuhkan. Saya akan menawarkan script ke proyek rpmdev untuk dimasukkan.
sumber
Saya menyusun ekspresi reguler yang sesuai dengan semua data yang dapat saya uji. Saya harus menggunakan campuran pertandingan serakah dan tidak serakah. Yang mengatakan, inilah versi perl dan python saya:
Perl:
Python:
Saya lebih suka memiliki regex yang berasal dari proyek RPM. Yang saya temukan di atas harus saya lakukan untuk saat ini.
sumber
.*
kecuali Anda BENAR-BENAR ingin mencocokkan apa pun). Senang melihat bahwa Anda menemukan sendiri, meskipun!AdbeRdr9.5.5-1_i486linux_enu.rpm
) yang memecah regex Anda diuraikan di atas.File Rpm dapat memiliki beberapa nama file yang funky dalam kasus-kasus ekstrem, tetapi umumnya Anda dapat membagi NVR pada tanda hubung. Tangkapannya adalah bagian N (nama) dari NVR dapat berisi tanda hubung dan garis bawah, tetapi V (versi) dan R (rilis) dijamin tidak memiliki tanda hubung asing. Jadi Anda bisa mulai dengan memotong bagian VR untuk mendapatkan Nama.
Berdasarkan itu Anda dapat mengisolasi bagian Versi dan Rilis.
Pisahkan tanda hubung lagi untuk mengisolasi bagian yang Anda butuhkan. Dan jelas membersihkan lengkungan dan ekstensi file rpm string, yang diberikan. Hanya memberi Anda gambaran tentang bagaimana hal itu bisa didekati di bash.
sumber
Gunakan opsi -q --queryformat dari rpm seperti yang dikatakan sebelumnya, jika Anda ingin melakukan ini pada paket yang tidak diinstal Anda dapat menentukan rpm dengan
-p
opsi, seperti ini:misalnya
memberi saya
jadi hanya memisahkan nama file itu salah!
jadi perhatikan , ini bukan detail rpm yang benar, misal
1.fedora
sebenarnya1.fc10
di rpm.sumber
Jika Anda terbiasa dengan Ekspresi Reguler dan / atau Perl, itu cukup mudah.
atau regex saja:
Jika Anda membaginya, itu:
[^\-]+
(melarikan diri karena tanda hubung memiliki makna khusus dalam kelompok karakter)[^\-]+?
([^\-]+?)
([^\-]+?)-
.rpm
):([^\-]+?)-(.*).rpm$
(dolar berarti "ujung jalur")m#([^\-]+?)-(.*).rpm$#
Selesai! Hanya mendapatkan kedua bagian dalam variabel
$1
dan$2
Komentar pada liner pertama:
Saya berada di direktori dengan banyak file rpm, karenanya
ls
.perl -p
setara dengan;Yang menjelaskan bahwa saya harus memasukkan null-string
$_
untuk menghindari perl mencetak kembali garis setelah saya mengekstrak dan mencetaknya. Perhatikan bahwa saya bisa menggunakan substitusi untuk mencegah 'peretasan' kecil ini.sumber
module-init-tools-3.9-21.el6_4.x86_64.rpm
.IMHO cara shell paling sederhana adalah:
Yaitu: membalikkan setiap baris, menggunakan slash cut hanya bagian pertama ( emanelif ), kemudian menggunakan tanda hubung semua kecuali dua bagian pertama (yaitu meninggalkan ESAELER termasuk emanelif eth fo tser dan NOISREV ) dan membalikkan enil kembali.
Dengan file contoh Anda:
Untuk mendapatkan bagian lain adalah latihan membaca cut (1) .
sumber
Anda bisa memanfaatkannya
dnf info
. Berikut ini contoh skrip Bash untuk mendapatkan nilai dan ditetapkan sebagai variabel:Ini akan memberikan hasil bahkan jika paket tidak diinstal.
sumber