需要一些脚本帮助。这里是问题。我有一套python包(文件)
beautifulsoup4-4.12.2-py3-none-any.whl
certifi-2023.7.22-py3-none-any.whl
charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
google-3.0.0-py2.py3-none-any.whl
idna-3.4-py3-none-any.whl
protobuf3-0.2.1.tar.gz
protobuf-3.19.6-py2.py3-none-any.whl
proton-0.9.1.tar.gz
python-qpid-proton-0.38.0.tar.gz
redis-4.5.5-py3-none-any.whl
requests-2.31.0-py3-none-any.whl
robotframework-6.1.1-py3-none-any.whl
robotframework_requests-0.9.1-py3-none-any.whl
robotframework-run-keyword-async-1.0.8.tar.gz
soupsieve-2.5-py3-none-any.whl
urllib3-2.0.7-py3-none-any.whl
字符串
我需要解析每个文件名以获取软件包名称及其版本。我有一些工作,而其他人失败。基本上上面的列表应该找到每个名称和版本。
beautifulsoup4 4.12.2
certifi 2023.7.22
charset-normalizer 3.3.1
google 3.0.0
idna 3.4
protobuf3 0.2.1
protobuf 3.19.6
proton 0.9.1
python-qpid-proton 0.38.0
redis 4.5.5
requests 2.31.0
robotframework 6.1.1
robotframework-requests 0.9.1
robotframework-run-keyword-async 1.0.8
soupsieve 2.5
urllib3 2.0.7
型
我已经尝试过cut,grep,sed,和awk来实现这个功能,但是名字中出现的数字,多位数版本,模式的不一致,会导致一个或另一个方法失败。你也会注意到charset和robotframework-requests更改为a -,但是我希望这些情况不太常见,当它发生时,我可以解决这个问题。
这是我当前的脚本逻辑(fullName是上面列出的文件名),但如果对certifici,charset-normalizer,idna,soupsieve和robotframework-requests失败,
version=`echo "$fullName" | sed -nre 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p'`
artifactId=`echo "$fullName" | sed -r "s/-${version}.*//g"`
型
特别是对于当前脚本,对于那些不工作的脚本,构建工件和版本为:
beautifulsoup4 4
protobuf3-0.2.1.tar.gz 3
urllib3-2.0.7-py3-none-any.whl 3
型
如果任何人有一个很好的方法来解析artifactId/版本与regex或任何其他bash脚本的方法,我愿意尝试任何东西。
谢谢
4条答案
按热度按时间57hvy0tb1#
如果输入是存储在文件中或来自管道的名称列表,那么
sed
或awk
解决方案将是更好的方法,因为这将比shell循环阅读输入更有效(参见why-is-using-a-shell-loop-to-process-text-considered-bad-practice),但假设输入实际上只是存储在变量中的1个字符串,bash内置是更好的方法,因为这比生成一个子shell在管道中调用echo+sed更有效。因此,在第一个捕获组中将
_
s转换为-
s后,要对名为fullName
s的变量的内容进行regexp-match,并将所需的部分保存到名为version
的变量中,只需使用bash内置程序即可:字符串
使用shell循环从您提供的示例输入填充
fullName
,以便我们可以演示(同样,您不会编写shell循环来操作文本):型
请参阅:
BASH_REMATCH
${var//old/new}
的xa9qqrwz2#
使用
sed
,您可以在最后一次出现-
之后使用2个捕获组和捕获和编号格式,然后是-
或.
如果版本中必须至少有一个点,则可以将
(\.[0-9]+)*
更改为(\.[0-9]+)+
字符串
输出
型
oiopk7p53#
如果你只有一个Input_file,并且你想从它里面得到值,那么试试下面的方法。用GNU
awk
编写和测试。仅用显示的示例编写和测试。字符串
tjvv9vkg4#
有什么想法。
如果您可以使用外部python包,您可以使用wheel-filename作为wheel(*.whl)文件,请首先通过以下方式安装它:
字符串
那么您可以按照以下方式使用它,假设您有
list.txt
,如下所示型
使用以下内容创建nameparser.py
型
然后执行
python3 nameparser.py
以获得以下输出型
如果你想知道更多关于命名轮子文件阅读PEP 427。