模式匹配

模式匹配

我正在尝试按照 Bash Cookbook 来了解 Bash 脚本。我正在使用示例 6.8 使用正则表达式进行测试。

我有以下脚本:

#!/usr/bin/env bash
# cookbook filename: trackmatch

for CDTRACK in *
do
     if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
then
    echo ${BASH_REMATCH[2]}
else
    echo Error $CDTRACK
fi
done

我将其应用于目录中的几个文件:

路德维希·范·贝多芬 - 02 - Adagio un poco mosso.ogg

路德维希·范·贝多芬 - 01 - Allegro.ogg

我总是收到返回错误。问题似乎与([[:alpha:][:blank:]]*)- ([[:digit:]]*) -代码部分有关。当我的 if 语句为:if [[ "$CDTRACK" =~ "(.*)$" ]]那么就没有错误。

关于我做错了什么有什么想法吗?

我在 AWS Bash v 4.2 上运行代码

答案1

外壳检查是 bash 编程的良好开端。它给出了非常有用的提示:

Line 6:
if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
                    ^-- SC2076: Don't quote rhs of =~, it'll match literally rather than as a regex.

正则表达式不能这样引用。使用转义特殊字符(基本上是空格)的工作示例:

if [[ "$CDTRACK" =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]

或作为格伦·杰克曼提议,仅引用其他字符(这对于使用不同语言的人来说看起来很奇怪,但也有效):

if [[ "$CDTRACK" =~ ([[:alpha:][:blank:]]*)"- "([[:digit:]]*)" - "(.*)$ ]]

Oneliner 用于测试现有字符串:

if [[ "Ludwig van Beethovern - 02 - Adagio un poco mosso.ogg" =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]; then echo "${BASH_REMATCH[2]}"; fi

相关内容