为什么正则表达式在 bash/ksh 中不起作用,而在命令行中却可以正常工作
Why Regex doesn't work in bash/ksh while it works fine in command line
我想使用以下正则表达式模式排除任何以“.ses”结尾的文件或没有扩展名的文件。它在命令行中工作正常,但在 shell (bash/ksh).
中不行
正则表达式模式:"\.(?!ses$)([^.]+$)"
文件名示例:
"/test/path/test file with spaces.__1" (expected true)
"/test/path/test file with spaces.ses" (expected false)
"/test/path/test file with spaces" (expected false)
"/test/path/test file with spaces.txt" (expected true)
FILE_NAME="/test/path/test file with spaces.__1"
PATTERN_STR="\.(?!ses$)([^.]+$)"
if [[ "${FILE_NAME}" =~ ${PATTERN_STR} ]]; then
Match_Result="true"
else
Match_Result="false"
fi
echo $Match_Result
它 returns 是“真”,但 shell 是“假”。有人知道为什么吗?
我只会使用带有合适 glob 的 case 语句:
case "${FILE_NAME##*/}" in
*.ses)
Match_Result=false
;;
*.*)
Match_Result=true
;;
*)
Match_Result=false
;;
esac
考虑使用数组而不是做空白体操。
您可以反转您的逻辑,让所有末尾包含 .ses
或在最后一个 /
.
后不包含点的字符串都失败
然后,你可以使用this script:
#!/bin/bash
declare -a arr=("/test/path/test file with spaces.__1"
"/test/path/test file with spaces.ses"
"/test/path/test file with spaces"
"/test/path/test file with spaces.txt")
# true false false true
PATTERN_STR='(/[^/.]+|\.ses)$'
for FILE_NAME in "${arr[@]}"; do
if [[ "$FILE_NAME" =~ $PATTERN_STR ]]; then
Match_Result="false"
else
Match_Result="true"
fi
echo $Match_Result
done;
输出:
true
false
false
true
详情:
(
- 捕获组的开始:
/[^/.]+
- /
然后是 /
和 .
以外的一个或多个字符
|
- 或者
\.ses
- .ses
)
- 分组结束
$
- 字符串结尾。
使用 shopt -s nocasematch
/shopt -u nocasematch
启用不区分大小写的版本(参见 )。
我想使用以下正则表达式模式排除任何以“.ses”结尾的文件或没有扩展名的文件。它在命令行中工作正常,但在 shell (bash/ksh).
中不行正则表达式模式:"\.(?!ses$)([^.]+$)"
文件名示例:
"/test/path/test file with spaces.__1" (expected true)
"/test/path/test file with spaces.ses" (expected false)
"/test/path/test file with spaces" (expected false)
"/test/path/test file with spaces.txt" (expected true)
FILE_NAME="/test/path/test file with spaces.__1"
PATTERN_STR="\.(?!ses$)([^.]+$)"
if [[ "${FILE_NAME}" =~ ${PATTERN_STR} ]]; then
Match_Result="true"
else
Match_Result="false"
fi
echo $Match_Result
它 returns 是“真”,但 shell 是“假”。有人知道为什么吗?
我只会使用带有合适 glob 的 case 语句:
case "${FILE_NAME##*/}" in
*.ses)
Match_Result=false
;;
*.*)
Match_Result=true
;;
*)
Match_Result=false
;;
esac
考虑使用数组而不是做空白体操。
您可以反转您的逻辑,让所有末尾包含 .ses
或在最后一个 /
.
然后,你可以使用this script:
#!/bin/bash
declare -a arr=("/test/path/test file with spaces.__1"
"/test/path/test file with spaces.ses"
"/test/path/test file with spaces"
"/test/path/test file with spaces.txt")
# true false false true
PATTERN_STR='(/[^/.]+|\.ses)$'
for FILE_NAME in "${arr[@]}"; do
if [[ "$FILE_NAME" =~ $PATTERN_STR ]]; then
Match_Result="false"
else
Match_Result="true"
fi
echo $Match_Result
done;
输出:
true
false
false
true
详情:
(
- 捕获组的开始:/[^/.]+
-/
然后是/
和.
以外的一个或多个字符
|
- 或者\.ses
-.ses
)
- 分组结束$
- 字符串结尾。
使用 shopt -s nocasematch
/shopt -u nocasematch
启用不区分大小写的版本(参见