![rpm -qa 的输出,如何仅提取包的名称?](https://linux22.com/image/1259473/rpm%20-qa%20%E7%9A%84%E8%BE%93%E5%87%BA%EF%BC%8C%E5%A6%82%E4%BD%95%E4%BB%85%E6%8F%90%E5%8F%96%E5%8C%85%E7%9A%84%E5%90%8D%E7%A7%B0%EF%BC%9F.png)
该命令的输出格式rpm -qa
如下:
abrt-1.1.14-1.fc14.x86_64
abrt-addon-ccpp-1.1.14-1.fc14.x86_64
abrt-addon-kerneloops-1.1.14-1.fc14.x86_64
abrt-addon-python-1.1.14-1.fc14.x86_64
abrt-desktop-1.1.14-1.fc14.x86_64
abrt-gui-1.1.14-1.fc14.x86_64
abrt-libs-1.1.14-1.fc14.x86_64
abrt-plugin-bugzilla-1.1.14-1.fc14.x86_64
abrt-plugin-logger-1.1.14-1.fc14.x86_64
abrt-plugin-runapp-1.1.14-1.fc14.x86_64
有人能告诉我如何可靠地删除版本、发行版和 arch 部分,以便我最终得到
abrt
abrt-addon-ccpp
abrt-addon-kerneloops
abrt-addon-python
abrt-desktop
abrt-gui
abrt-libs
abrt-plugin-bugzilla
abrt-plugin-logger
abrt-plugin-runapp
我宁愿避免尝试为 sed 构建正则表达式,因为我预计它会很复杂,以便支持诸如 super-3d-editor-0.1-1.fc14.x86_64 或类似的名称。我确信我不是第一个想要这种过滤的人,因此我在这里询问是否已经存在某种解决方案。
更新: 上面的“或类似”注释暗示您对 rpm 包名称的样子有一定的了解。它们中的大多数都像上面介绍的那样“好看”,但也有条目采用更多样化的编号方案:
fxload-2002_04_11-9.fc12.x86_64
GitPython-0.2.0-0.3.beta1.fc14.noarch
ModemManager-0.4-4.git20100720.fc14.x86_64
python-peak-rules-0.5a1.dev-12.a1.dev.20100803svn2646.fc14.noarch
pytz-2010h-3.fc14.noarch
还要注意,有些软件包的名称中包含版本号,例如
java-1.5.0-gcj-1.5.0.0-34.fc14.x86_64
java-1.6.0-openjdk-1.6.0.0-49.1.9.3.fc14.x86_64
java-1.6.0-openjdk-devel-1.6.0.0-49.1.9.3.fc14.x86_64
甚至还有一些缺少发布/架构(这些可能很难处理,我可以接受无法处理这些问题)
bouml-doc-4.3.2-3.noarch
fedora-release-14-1.noarch
glibc-2.12.90-21.i686
basesystem-10.0-3.noarch
ivtv-firmware-20080701-20.noarch
gpg-pubkey-97a1071f-4c49d6fe
这就是为什么我要求一种可靠的方法来做到这一点;我知道创建一个近似的 sed 正则表达式是可能的,但它必然无法处理很多行。
(我知道可以使用 --queryformat 格式化 rpm 的输出,但是这对我没有帮助,因为我想通过与rpm -qa
一年前生成的列表进行比较来比较我今天安装了哪些软件包。)
答案1
既然你已经筋疲力尽,你需要把去年的累赘除去。如果它足够一致,始终保持库存格式,如下所示:
#!/usr/bin/python
import sys
for line in sys.stdin:
if line.startswith('gpg-pubkey-'):
continue # We don't care about imported keys. G'bye!
try:
woarch = line.rsplit('.', 1)[0] # Bye, arch!
worel = woarch.rsplit('-', 1)[0] # Bye, release!
wover = worel.rsplit('-', 1)[0] # Bye, version!
except Exception as e: # Well nuts...
print ('%s ** %s') % (e, line)
continue
print (wover)
只需将去年的垃圾重定向到其中,您就会获得重要的名称。
答案2
您可以使用 rpm 的--qf
queryformat 参数。您给它一个格式字符串,其中可以用 包围标签%{}
。您可以使用rpm --querytags
我猜你想要的是类似这样的东西:
rpm -qa --qf "%{NAME}\n"
答案3
这远非完美,但值得尝试。
$ rpm -qa --qf "%{NAME}\n" > currentlist
$ join -t . -v 1 oldlist currentlist # show packages in oldlist not in currentlist
$ join -t . -v 2 oldlist currentlist # show packages in currentlist not in oldlist
此sed
命令对除标记为“多样”的组之外的所有组都有效:
sed 's/-[^-]*-[^-]*\.[^.]*\.[^.]*$//'
我相信它的工作原理与 Ignacio 的 Python 脚本类似。
答案4
不确定为什么你认为--queryformat
这不会帮助你...为什么不按照前面的答案建议的那样,使用它从名称中分离出版本和体系结构?这样,你可以rpm -qa
以 CSV 或制表符分隔格式输出列表以供以后处理。