用于检查仅数字的正则表达式是否存在于下划线而非字符之后

Rah*_*hul 5 shell wildcards

我的 shell 脚本中有 if 循环,它将检查表名是否存在任何整数,这是我指定的条件:

if [[ "$able_name" == *[0-9]* ]] 
Run Code Online (Sandbox Code Playgroud)

一般来说,表名会是这样的:

tablename_000 
Run Code Online (Sandbox Code Playgroud)

或者

tablename_001 
Run Code Online (Sandbox Code Playgroud)

但是我有一个新文件,其名称类似于table_V2. 由于名称与正则表达式匹配,因此进入此循环。我怎样才能避免这种情况?if只有在下划线之后存在整数而不是任何其他字符时,它才应该进入循环。

Sté*_*las 5

使用标准sh语法:

case ${table_name##*_} in
  ("$table_name" | "" | *[!0-9]*) echo >&2 incorrect;;
  (*) echo correct;;
esac
Run Code Online (Sandbox Code Playgroud)

那是检查从$table_name最右边的所有内容中剥离_出来的既不是$table_name它本身(这意味着$table_name没有_),也不是空字符串,也不是包含非数字字符。

将字符串与正expr则表达式匹配的标准命令是虽然它有一些问题并且不会产生非常清晰的代码:

if expr " $table_name" : '.*_[0-9]\{1,\}$' > /dev/null; then
  echo Correct
else
  echo >&2 Incorrect
fi
Run Code Online (Sandbox Code Playgroud)

前导空间是为了避免$table_namelike+或值的问题--help。正则表达式隐式地锚定在开头(因此是.*)而不是结尾(因此是$),并且结果(这里是 0 或 1)除了反映在退出状态中之外,还会在标准输出上输出,因此重定向到 /dev/null。

一些[实现,如[内置的zshyash有一个=~运算符(使用 ERE,但您可以使用 将其更改为 PCRE zsh):

if [ "$table_name" '=~' '_[0-9]+$' ]; then
   echo Correct
else
   echo >&2 Incorrect
fi
Run Code Online (Sandbox Code Playgroud)

bash,zsh并且在它们的构造中ksh93有一个=~运算符[[...]],尽管语法和行为 wrt 引用因实现而异。最好是使用@BLayer 已经显示的变量

zsh -o extendedglobksh(或bash -O extglobzsh -o kshglob这种支持的一个子集ksh水珠)有水珠运营商在功能上等同于正则表达式尽管有不同的语法。

翻译 RE -> ksh-glob / zsh-glob:

  • [0-9]-> [0-9]/[0-9]
  • x+-> +(x)/x##
  • $^-> 隐式/隐式
  • . -> ?
  • .*-> *(或*(?))/ *(或?#

所以在ksh(或bash -O extglobzsh -o kshglob)中:

case $table_name in
  (*_+([0-9]) echo correct;;
  (*) echo >&2 incorrect;;
esac
Run Code Online (Sandbox Code Playgroud)

zsh -o extendedglob

case $table_name in
  (*_[0-9]##) echo correct;;
  (*) echo >&2 incorrect;;
esac
Run Code Online (Sandbox Code Playgroud)

zsh也有<x-y>扩展的 glob 运算符来匹配十进制数从xtoy所以你也可以写它(*_<->) echo correct

在这些 shell 中,这些 glob 也可以用在=aka== [[...]]运算符的右侧。


Ini*_*ian 2

建议为此使用正则表达式选项,但也可以使用仅包含数字的普通 glob。例如你可以做类似的事情

for file in tablename_[0-9]*; do
    [ -f "$file" ] || continue
    printf "%s\n" "$file"
done
Run Code Online (Sandbox Code Playgroud)

使用 中的正则表达式运算符bash,您可以执行类似的操作,

for file in tablename_*; do
    if [[ $file =~ _([[:digit:]]+)$ ]]; then
        printf "%s\n" "$file"
    fi
done
Run Code Online (Sandbox Code Playgroud)