Shell test to find a pattern in a string

In any POSIX-compatible shell you can do:

case $line in (*"$PWD"*)
#    whatever your then block had
;;esac

This works in bash, dash, and just about any other shell you can name.

It can also be used to handle multiple possibilities easily. For example:

case $line in 
(*"$PWD"*)
    echo \$PWD match\!
;;
(*"$OLDPWD"*)
    echo \$OLDPWD match\!
;;
(*)
    ! echo no match\!
;;esac

You can also use alternation:

case $line in (*"$PWD"*|*"$OLDPWD"*)
    echo '$OLDPWD|$PWD match!'
;;esac

Note the use of quoting above:

  1. case $line ...
    • The object of a case statement will not be split on either $IFS or be used as a pattern for filename gen. This is similar to the way the left argument in a [[ test is treated.
  2. (*"$PWD"*)
    • Here also a shell expansion is not subjected to either $IFS or filename generation - an unquoted expansion will neither split nor glob.
    • But an unquoted expansion here might be construed as a pattern rather than a literal string though, and so an expansion might mean more than one thing depending on whether or not it is quoted.
    • It is important to quote any variable used in a pattern that should be literally interpreted, in the same way you would quote pattern chars which you wanted interpreted literally.
    • For example, if $PWD contained a * and was not quoted it would be construed as a pattern object and not as a literal * to be searched for.

Yes, recent versions of bash can do this:

$ pwd
/home/terdon
$ line="I'm in /home/terdon"
$ [[ "$line" =~ "$PWD"$ ]] && echo yes
yes

The same syntax works in zsh and ksh but not in dash. As far as I know, dash has no such capabilities.

Note that your regex is checking whether the variable $line ends with $PWD. To check if $PWD matches anywhere in $line, remove the $:

$ line="I'm in /home/terdon, are you?"
$ [[ "$line" =~ "$PWD" ]] && echo yes
yes