提问人:Simon Bagley 提问时间:10/6/2023 最后编辑:Simon Bagley 更新时间:10/6/2023 访问量:38
bash 脚本可以从文件名列表中提取名称、版本号和扩展名吗
Can a bash script extract name, version number and extension from a list of filenames
问:
我在创建 Bash 脚本时遇到问题,该脚本将从文件名列表中提取应用程序名称、版本号和可能的扩展名,例如:
- 应用程序名称-1-v1.2.3.AppImage
- 应用名称2-V999.2.31.AppImage
- 另一个应用程序-v123.456.789
- 然而-另一个-例子-4-V0.0.1.extA
对于上述示例,应用程序名称为:
- 应用程序名称-1
- 应用名称2
- 另一个应用程序
- 然而-另一个例子-4
版本号为:
- 1.2.3
- 999.2.31
- 123.456.789
- 0.0.1
扩展将是:
- “应用图像”
- “应用图像”
- ""
- “extA”
所有文件名的版本号前面都以 v 或 V 开头,但可能有扩展名,也可能没有扩展名。
我尝试了在 Google Bard 的帮助下创建的以下脚本:
#!/bin/bash
# Function to parse a filename and separate out the base name, version number, and extension
function parse_filename() {
# Get the base name of the file
basename=${1##*/}
# Get the extension of the file
extension=${basename##*.}
# Remove the extension from the base name
basename=${basename%.*}
# Get the version number of the file
version=${basename##*-}
# Strip any leading or trailing spaces from the base name and version number
basename=${basename## }
basename=${basename%% }
version=${version## }
version=${version%% }
# If the version number is not in the form digits.digits.digits, then set the version number to an empty string
if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
version=""
fi
# If the version number is empty, then the version number is the extension
if [[ -z "$version" ]]; then
version="$extension"
fi
# If the base name is empty, then the base name is the filename without the extension
if [[ -z "$basename" ]]; then
basename=${1%.*}
fi
}
echo "Running script: $0"
# Get the list of filenames from the user
filenames=("$@")
# Iterate over the list of filenames and parse each one
for filename in "${filenames[@]}"; do
echo "Processing filename: $filename"
# Parse the filename and get the base name, version number, and extension
parse_filename "$filename"
# Print the results to the: console
echo "Base name: $basename"
echo "Version number: $version"
echo "Extension: $extension"
echo
done
但是,这不会产生正确的输出:
Running script: ./filename-parser.sh
Processing filename: name-of-application-1-v1.2.3.AppImage
Base name: name-of-application-1-v1.2.3
Version number:
Extension:
Processing filename: app-name2-V999.2.31.AppImage
Base name: app-name2-V999.2.31
Version number:
Extension:
Processing filename: another-application-v123.456.789
Base name: another-application-v123.456
Version number:
Extension:
Processing filename: yet-another-example-4-V0.0.1.extA
Base name: yet-another-example-4-V0.0.1
Version number:
Extension:
这在 bash 脚本中是否可能,或者我是否需要求助于 Python 或其他东西。
答:
1赞
Benjamin W.
10/6/2023
#1
您可以使用正则表达式,如下所示:
#!/usr/bin/env bash
files=(
name-of-application-1-v1.2.3.AppImage
app-name2-V999.2.31.AppImage
another-application-v123.456.789
yet-another-example-4-V0.0.1.extA
)
re='(.*)-[vV](([[:digit:]]+\.){2}[[:digit:]]+)(\.(.*))?'
for file in "${files[@]}"; do
printf 'Processing: %s\n' "$file"
[[ $file =~ $re ]]
printf 'Base name: %s\n' "${BASH_REMATCH[1]}"
printf 'Version number: %s\n' "${BASH_REMATCH[2]}"
printf 'Extension: %s\n\n' "${BASH_REMATCH[5]}"
done
评论
0赞
Simon Bagley
10/6/2023
太好了,这很完美。我显然需要学习如何正确使用正则表达式!
1赞
Paul Hodges
10/6/2023
#2
BASH_REMATCH
是一个不错的选择,但如果复杂的正则表达式让您头疼,您通常可以使用基于 glob 的标准参数扩展来完成相同的操作。
$: cat tst
#!/bin/bash
while read -r fn; do app=${fn%-[vV][0-9]*}; ext=${fn##*[0-9.]}; ver=${fn%.$ext}; ver=${ver#*-[Vv]};
printf "Filename: %-40.40s App: %-25.25s Version: %-10.10s Extenssion: %-10.10s\n" "$fn" "$app" "$ver" "$ext"
done < files
P2759474@CORTOPSALBSC7Q9 2023-10-06,10:20:18 /tmp
$: ./tst
Filename: name-of-application-1-v1.2.3.AppImage App: name-of-application-1 Version: 1.2.3 Extenssion: AppImage
Filename: app-name2-V999.2.31.AppImage App: app-name2 Version: 999.2.31 Extenssion: AppImage
Filename: another-application-v123.456.789 App: another-application Version: 123.456.78 Extenssion:
Filename: yet-another-example-4-V0.0.1.extA App: yet-another-example-4 Version: 0.0.1 Extenssion: extA
无论哪种情况,您只需要识别和编码您的假设。
我使用了这些: :
dash,V,digit 开始版本(不区分大小写):
扩展名不能有数字${fn%-[vV][0-9]*}
${fn##*[0-9.]}
${fn%.$ext}
/ ${ver#*-[Vv]}
:删除最高版本启动和任何扩展名
任何正则表达式也编码类似的假设,但根据您的品味和技能组合,可能更容易或可能更难阅读。如果文件很多,单个正则表达式解析可能会更快。
评论