Issue
I am having trouble creating a Bash script that will extract application name, version number and possible extension from a list of filenames such as:
- 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
For the above examples, the application names would be:
- name-of-application-1
- app-name2
- another-application
- yet-another-example-4
The version numbers would be:
- 1.2.3
- 999.2.31
- 123.456.789
- 0.0.1
The extensions would be:
- "AppImage"
- "AppImage"
- ""
- "extA"
All filenames have a version number preceded by v or V, but may or may not have an extension.
I have tried the following script created with the help of 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
This does not produce the correct output though:
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:
Is this even possible in a bash script, or do I need to resort to Python, or something else.
Solution
You could use a regular expression, something like this:
#!/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
Answered By - Benjamin W. Answer Checked By - Mildred Charles (WPSolving Admin)