RPM 이름을 구성 요소로 구문 분석 NAME 및 $

공식 RPM 도구 패키지의 일부인 이름 구문 분석 도구가 있습니까?

파일 이름 목록이 있습니다. 각각은 RPM 패키지의 파일 이름입니다. 실제 패키지가 없으며 파일 이름 만 있습니다. 각각에 대해 패키지 이름과 버전 ($ NAME 및 $ VERSION)을 추출해야합니다. 내가 필요한 이유는 “yum install $ VERSION”이 $ VERSION을 설치하는지 확인하는 스크립트를 작성하고 있기 때문입니다. 패키지를 빌드하고 올바르게 업로드되었는지 확인하는 시스템의 일부입니다.

파일 이름 목록은 다음과 같습니다.

$ 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

작업을 수행하는 BASH 함수 인 다음 코드 를 찾았 습니다 .

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

효과가있다. 대개. 몇 가지 예외가 있습니다 :

$ parse_rpm CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
sei_dnsmaster 1.0 99.el6 x86_64

버전을 올바르게 얻지 못했습니다 (1.0-99 여야 함)

rpmdev 패키지 에이 작업을 올바르게 수행하는 도구가 있는지 궁금합니다. (2) 그렇지 않으면 공식 정규식이 있습니까? (3) 그 정규 표현식과 파이썬은 무엇입니까?

미리 감사드립니다!



답변

이 작업을 수행 할 필요는 없습니다. RPM에는 쿼리 형식 인수가있어 수신하려는 데이터를 정확하게 지정할 수 있습니다. 지정하지 않으면 줄 끝없이 출력됩니다.

예를 들어 :

rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}" -q coreutils
rpm --queryformat "The version of %{NAME} is %{VERSION}\n" -q coreutils

rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}" -qp file.rpm

사용할 수있는 전체 변수 목록은 다음을 통해 얻을 수 있습니다.

rpm --querytags

의 경우 RELEASE와 같은 출력 84.el6은 정상이며 예상되는 것입니다. 실제로는 패키지별로 또는 배포 용으로 RPM 패키지가 버전 화되는 방식이기 때문입니다.


답변

필자가 찾고있는 것을 수행하는 공식적인 방법은 Python에서 들었습니다.

from rpmUtils.miscutils import splitFilename

(n, v, r, e, a) = splitFilename(filename)

필요한 것을 수행하는 짧은 Python 프로그램을 작성했습니다. 포함을 위해 스크립트를 rpmdev 프로젝트에 제공 할 것입니다.


답변

테스트 할 수있는 모든 데이터에 맞는 정규식을 해결했습니다. 욕심쟁이와 욕심없는 성냥을 혼합해서 사용해야했습니다. 즉, 여기 내 펄 및 파이썬 버전이 있습니다 :

펄 :

#! /usr/bin/perl

foreach (@ARGV) {
    ($path, $name, $version, $release, $platform,
      @junk) = m#(.*/)*(.*)-(.*)-(.*?)\.(.*)(\.rpm)#;
    $verrel = $version . '-' . $release;

    print join("\t", $path, $name, $verrel, $version, $rev, $platform), "\n";
}

파이썬 :

#! /usr/bin/python

import sys
import re

for x in sys.argv[1:]:
    m = re.search(r'(.*/)*(.*)-(.*)-(.*?)\.(.*)(\.rpm)', x)
    if m:
        (path, name, version, release, platform, _) = m.groups()
        path = path or ''
        verrel = version + '-' + release
        print "\t".join([path, name, verrel, version, release, platform])
    else:
        sys.stderr.write('ERROR: Invalid name: %s\n' % x)
        sys.exit(1)

오히려 RPM 프로젝트에서 나오는 정규식을 원합니다. 내가 위에서 발명 한 것은 지금해야 할 것입니다.


답변

Rpm 파일은 극단적 인 경우 약간의 펑키 파일 이름을 가질 수 있지만 일반적으로 NVR을 하이픈으로 분할 할 수 있습니다. catch는 NVR의 N (이름) 부분에 하이픈과 밑줄이 포함될 수 있지만 V (버전) 및 R (릴리스)에는 불필요한 하이픈이없는 것이 보장됩니다. 따라서 VR 부분을 잘라서 이름을 도출하는 것으로 시작할 수 있습니다.

$ RPM=/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-2.8-3.el6.x86_64.rpm
$ echo ${RPM%-*-*}
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial

이를 바탕으로 버전 및 릴리스 부분을 분리 할 수 ​​있습니다.

echo ${RPM#${RPM%-*-*}-*}
2.8-3.el6.x86_64.rpm

하이픈을 다시 분할하여 필요한 부분을 분리하십시오. 그리고 분명히 아치 및 rpm 파일 확장자 문자열을 제거하십시오. bash에서 어떻게 접근 할 수 있는지에 대한 아이디어를 제공합니다.


답변

이전에 말한 것처럼 rpm에서 -q –queryformat 옵션을 사용하십시오. 설치되지 않은 패키지에서이 작업을 수행하려면 다음과 같이 -p옵션으로 rpm을 지정할 수 있습니다 .

rpm -q -p ./Downloads/polysh-0.4-1.noarch.rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}\n"
polysh 0.4 1 noarch

예 :

$ ls ./Downloads/*.rpm
./Downloads/adobe-release-x86_64-1.0-1.noarch.rpm
./Downloads/nautilus-dropbox-1.6.0-1.fedora.x86_64.rpm
./Downloads/playonlinux-yum-4-1.noarch.rpm
./Downloads/skype-4.2.0.11-fedora.i586.rpm
./Downloads/dbview-1.0.4-2.1.x86_64.rpm
./Downloads/openmotif22-libs-2.2.4-192.1.3.x86_64.rpm
./Downloads/polysh-0.4-1.noarch.rpm

나에게 준다

adobe-release-x86_64 1.0 1 noarch
dbview 1.0.4 2.1 x86_64
nautilus-dropbox 1.6.0 1.fc10 x86_64
openmotif22-libs 2.2.4 192.1.3 x86_64
playonlinux-yum 4 1 noarch
polysh 0.4 1 noarch
skype 4.2.0.11 fc16 i586

파일 이름을 분할하는 것이 잘못되었습니다!

for filename in """<paste list here>""".split():
    print splitFilename(filename)

('./Downloads/adobe-release-x86_64', '1.0', '1', '', 'noarch')
('./Downloads/nautilus-dropbox', '1.6.0', '1.fedora', '', 'x86_64')
('./Downloads/playonlinux-yum', '4', '1', '', 'noarch')
('./Downloads/skype', '4.2.0.11', 'fedora', '', 'i586')
('./Downloads/dbview', '1.0.4', '2.1', '', 'x86_64')
('./Downloads/openmotif22-libs', '2.2.4', '192.1.3', '', 'x86_64')
('./Downloads/polysh', '0.4', '1', '', 'noarch')

그래서 관심을 지불 ,이 예를 들어, 회전의 정확한 세부 사항 아닌 1.fedora실제로 1.fc10회전 수에서.


답변

정규식 및 / 또는 Perl에 익숙한 경우 매우 쉽습니다.

 ls | head | perl -p -e 'm#([^\-]+?)-(.*).rpm$#; print "$1 $2\n";$_=""'

또는 정규식 만 :

m#([^\-]+?)-(.*).rpm$#

분할하면 다음과 같습니다.

  • 하이픈 이외의 문자, 하나 이상의 문자 : [^\-]+(문자 그룹에서 하이픈이 특별한 의미를 갖기 때문에 이스케이프 처리됨)
  • 첫 번째 하이픈 (및 마지막이 아닌) 이후에 일치를 중지하십시오. [^\-]+?
  • 이것을 캡처 그룹에 추가하십시오. ([^\-]+?)
  • 그런 다음 하이픈 : ([^\-]+?)-
  • 그런 다음 다른 캡처 그룹의 다른 것 (그러나 후행 .rpm) : ([^\-]+?)-(.*).rpm$ (달러는 “라인 끝”을 의미합니다)
  • 실제 일치 형식보다 : m#([^\-]+?)-(.*).rpm$#

완료! 그냥 변수의 두 부분을 취득 $1하고$2

첫 번째 라이너에 대한 의견 :

나는 rpm 파일이 많은 디렉토리에 있었기 때문에 ls.

perl -p 는;

perl -e 'while(<STDIN>){ chomp($_);  [YOUR CODE HERE] ; print($_); }'

$_압축을 풀고 사용자 정의 인쇄 한 후 펄이 인쇄되지 않도록 널 문자열을 넣어야한다고 설명 합니다. 이 작은 ‘핵’을 없애기 위해 대체를 사용할 수 있음에 유의하십시오.


답변

가장 간단한 쉘 방법은 다음과 같습니다.

ls | rev | cut -d/ -f1 | cut -d- -f3- | rev

즉, 첫 번째 부분 만 슬래시 컷을 사용하여 각 줄을 뒤집습니다. emanelif을 다음 하이픈을 모두 잘라하지만 첫 번째 두 부분 (뒤에 즉, 휴가 사용) ESAELER가 포함 TSER FO ETH emanelifNOISREV )와 역 enil의 뒷면.

예제 파일로 :

$ cat /tmp/packages.txt | rev | cut -d/ -f1 | cut -d- -f3- | rev
emacs-mercurial
emacs-mercurial-el
mercurial
mercurial-hgk
python-redis
redis
sei_dnsmaster
$

다른 부분을 얻으려면 cut (1) 을 읽으십시오 .