shell bash脚本可以从文件名列表中提取名称、版本号和扩展名吗

bqucvtff  于 2023-10-23  发布在  Shell
关注(0)|答案(2)|浏览(122)

我在创建一个Bash脚本时遇到了麻烦,该脚本将从文件名列表中提取应用程序名称,版本号和可能的扩展名,例如:

  1. name-of-application-1-v1.2.3.AppImage
  2. app-name2-V999.2.31.AppImage
  3. another-application-v123.456.789
  4. yet-another-example-4-V0.0.1.extA
    对于上述示例,应用程序名称为:
    1.应用名称1
    1.应用名称2
    1.另一应用
  5. yet-another-example-4
    版本号为:
  6. 1.2.3
  7. 999.2.31
  8. 123.456.789
    1.零点零一
    这些扩展将是:
    1.“AppImage”
    1.“AppImage”
    1.“”我的天
    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或其他东西。

jyztefdp

jyztefdp1#

你可以使用一个正则表达式,像这样:

#!/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
kxxlusnw

kxxlusnw2#

BASH_REMATCH是一个很好的选择,但是如果复杂的正则表达式给予您带来了麻烦,您通常可以使用标准的基于global的参数扩展来完成相同的任务。

$: 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

在任何一种情况下,你只需要识别和编码你的假设。
我用了这些:
${fn%-[vV][0-9]*}:* 破折号、V、数字 * 开始版本(不区分大小写)
${fn##*[0-9.]}:分机不能有数字
${fn%.$ext} / ${ver#*-[Vv]}:删除 up to version start和任何扩展名
任何正则表达式也编码类似的假设,但可能会或可能不会更容易/更难阅读基于您的品味和技能。如果有很多文件,单个正则表达式解析可能更快。

相关问题