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:
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.
- The object of a
(*"$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.
- Here also a shell expansion is not subjected to either
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