为什么RegEx匹配在我的Bash脚本中不起作用?

时间:2018-12-13 22:10:59

标签: regex bash shell

我正在学习bash脚本的正则表达式。但是,当我测试字符串匹配时,行始终无法通过。这是我正在测试的内容:

我有一个txt文件,其中包含“歌曲”列表:

$ cat soundtrack.txt
Ludwig Van Beethoven - 01 - Allero.oog
Ludwig Van Beethoven - 02 - Adag.mp3
Ludwig Van Beethoven - 03 - Beach.oog
Ludwig Van Beethoven - 04 - Caven Adven.wmv

我想使用Regex来获取数字的“曲目号”。

这是脚本:

$ cat soundtrack.sh
#!/bin/bash
IFS=$'\n'
for CD in `cat soundtrack.txt`
do
    if [[ "$CD" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
    then
        echo "Found ${BASH_REMATCH[2]}"
    fi
done 

但是,bash调试显示字符串无法匹配正则表达式:

$ bash -x soundtrack.sh
+ IFS='
'
++ cat soundtrack.txt
+ for CD in '`cat soundtrack.txt`'
+ [[ Ludwig Van Beethoven - 01 - Allero.oog =~ \(\[\[:alpha:]\[:blank:]]\*\)- \(\[\[:digit:]]\*\) - \(\.\*\)\$ ]]
+ for CD in '`cat soundtrack.txt`'
+ [[ Ludwig Van Beethoven - 02 - Adag.mp3 =~ \(\[\[:alpha:]\[:blank:]]\*\)- \(\[\[:digit:]]\*\) - \(\.\*\)\$ ]]
+ for CD in '`cat soundtrack.txt`'
+ [[ Ludwig Van Beethoven - 03 - Beach.oog =~ \(\[\[:alpha:]\[:blank:]]\*\)- \(\[\[:digit:]]\*\) - \(\.\*\)\$ ]]
+ for CD in '`cat soundtrack.txt`'
+ [[ Ludwig Van Beethoven - 04 - Caven Adven.wmv =~ \(\[\[:alpha:]\[:blank:]]\*\)- \(\[\[:digit:]]\*\) - \(\.\*\)\$ ]]

但是,如果我直接在外壳中使用相同的表达式进行测试,那么它将起作用:

$ if [[ "Ludwig Van Beethoven - 01 - Allero.oog" =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]; then echo yes; else echo no; fi
yes

我的脚本出了什么问题?我是否必须添加额外的配额或反斜杠?只是对我没有意义。

P.S。

$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

2 个答案:

答案 0 :(得分:1)

要注意的是,这些东西并不相同:

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

第一个版本是您在脚本中的编写方式,第二个版本是在shell中运行的方式。

也就是说,如果您将模式双引号,那么将按字面意义使用正则表达式符号。您不能将模式用双引号引起来。

答案 1 :(得分:1)

问题是您引用的正则表达式会占用所有特殊的正则表达式功能:仅引用文字位,尤其是如果它们是空格。第二个问题是您正在使用for循环读取文件:don't do that

while IFS= read -r CD; do
    if [[ "$CD" =~ ([[:alpha:][:blank:]]*)"- "([[:digit:]]*)" - "(.*) ]]
    then
        echo "Found ${BASH_REMATCH[2]}"
    fi
done < soundtrack.txt