Shell 测试以在字符串中查找模式

app*_*nic 9 shell string regular-expression

我只是想问一下是否有任何命令可以在常见的 shell(bash、dash、kornshell)上运行?它应该检查line变量是否包含路径的任何部分。

if [[ $line =~ "$PWD"$ ]] ;then
Run Code Online (Sandbox Code Playgroud)

mik*_*erv 14

在任何兼容 POSIX 的 shell 中,您都可以执行以下操作:

case $line in (*"$PWD"*)
#    whatever your then block had
;;esac
Run Code Online (Sandbox Code Playgroud)

这适用于bashdash以及您可以命名的任何其他 shell。

它还可用于轻松处理多种可能性。例如:

case $line in 
(*"$PWD"*)
    echo \$PWD match\!
;;
(*"$OLDPWD"*)
    echo \$OLDPWD match\!
;;
(*)
    ! echo no match\!
;;esac
Run Code Online (Sandbox Code Playgroud)

您还可以使用交替:

case $line in (*"$PWD"*|*"$OLDPWD"*)
    echo '$OLDPWD|$PWD match!'
;;esac
Run Code Online (Sandbox Code Playgroud)

注意上面引用的用法:

  1. case $line ...
    • case语句的对象不会被拆分$IFS或用作文件名生成的模式。这类似于[[处理测试中的左参数的方式。
  2. (*"$PWD"*)
    • 在这里,shell 扩展也不受$IFS文件名或文件名生成的影响 - 未加引号的扩展既不会 split 也不会 glob。
    • 但是,此处未加引号的扩展可能会被解释为模式而不是文字字符串,因此扩展可能意味着不止一件事,具体取决于它是否被引用。
    • 引用应该按字面解释的模式中使用的任何变量很重要,就像引用要按字面解释的模式字符一样。
    • 例如,如果$PWD包含 a*并且没有被引用,它将被解释为模式对象而不是*要搜索的文字。

  • 请注意,如果您需要 Bourne shell 的可移植性(例如对于某些古老的系统),您需要删除 `(`: `case $line in *"$PWD"*)` (2认同)

ter*_*don 4

是的,最新版本的 bash 可以做到这一点:

$ pwd
/home/terdon
$ line="I'm in /home/terdon"
$ [[ "$line" =~ "$PWD"$ ]] && echo yes
yes
Run Code Online (Sandbox Code Playgroud)

相同的语法适用于 zsh 和 ksh,但不适用于 dash。据我所知,dash没有这样的能力。

请注意,您的正则表达式正在检查变量$line 是否$PWD. 要检查$PWD中的任何位置是否匹配$line,请删除$

$ line="I'm in /home/terdon, are you?"
$ [[ "$line" =~ "$PWD" ]] && echo yes
yes
Run Code Online (Sandbox Code Playgroud)