
オペレーティングシステムパッケージとそのリリースバージョンのリストを含むファイルがあります。リリースバージョンではなくパッケージ名のみが必要です。
Linuxコマンドまたはスクリプトを使用してこれを達成するには?
例:
bind-export-libs-9.11.4-26.P2.el7_9.13
bind-export-libs-9.11.4-26.P2.el7_9.7
bind-libs-9.11.4-16.P2.el7
bind-libs-9.11.4-16.P2.el7_8.6
atk-2.28.1-1.el7
atk-2.28.1-2.el7
at-spi2-atk-2.26.2-1.el7
at-spi2-core-2.28.0-1.el7
上記のリストには、リリースバージョンに応じて重複したパッケージエントリが含まれています。
パッケージ名だけを抽出するにはどうすればよいですか?
答え1
あなたのリストは似たようなものによって生成されたと確信しているので、rpm -qa
バージョンではなくパッケージ名のみを表示するコマンドを提供します。これにより、後で多くの作業が節約されます。
rpm -qa --queryformat '%{NAME}\n' | sort
答え2
2番目のダッシュから最後のダッシュまですべてを整えます。
使用sed
:
sed -r 's/-[^-]+-[^-]+$//' file.txt
デフォルトでは、RPM NVRの汎用形式はです<name_possibly_containing_embedded_dashes_or_digits>-<version_never_containing_dashes>-<release_never_containing_dashes>
。ドットや数字には特別な意味がないため、検索は正しく機能しません。
出力でこれを実行すると、提案されたものとrpm -qa
まったく同じリストが生成されます。rpm -qa --queryformat '%{NAME}\n'
Artemの答え。単一のパッケージの複数のバージョンまたはリリースがインストールされていても、まだ重複したエントリがあることに注意してください(前者はカーネルパッケージまたはgpg-pubkeysの一般的な現象であり、後者はi686 / x86_64ライブラリの一般的な現象です)。sort -u
本当に一意の名前のリストだけが必要な場合は、結果を実行してください。
# these two should produce the same output:
rpm -qa | sed -r 's/-[^-]+-[^-]+$//'
rpm -qa --queryformat '%{NAME}\n'
答え3
トゥーティから出たと思います。回答このアプローチの代わりに正しいアプローチを指摘しましたが、これは参考のために残ります。
簡単に言えば、RPMファイル名の規則は複雑で、以下のように一意ではありません。したがって、場合によっては、実際に正しいパッケージ名とバージョンが何であるかを知る方法はありません。しかし、試してみることができます。
ただし、その複雑さのためにこれを行うことはできません。単にと正規表現を使ってを完了しますsed
。作業に適したツールではありません。代わりにRedhat / Fedoraの独自のツールを使用してください。このPythonスクリプトはあなたが望むものを提供します。
#!/usr/bin/env python3
from dnf.subject import Subject
from sys import stdin
from typing import Set
import hawkey
def filename_to_name_candidates(filename: str) -> Set[str]:
subj = Subject(filename)
return {
candidate.name
for candidate in subj.get_nevra_possibilities(forms=hawkey.FORM_NEVRA)
}
names = set()
for line in stdin:
try:
names = names | filename_to_name_candidates(line)
except:
pass
for name in sorted(names):
print(name)
どこかに保存して(例filename2packagename
:)実行可能にします(chmod 755 filename2packagename
)。その後、ファイル名をパイプできます。
./filename2packagename < listofnames.txt
答え4
使用sed
$ sed -En 's/([^.]*)-.*/\1/;G;/^(.*)\n.*\n\1/d;H;P' input_file
bind-export-libs
bind-libs
atk
at-spi2-atk
at-spi2-core