I just wanted to ask whether there is any command which would work on common shells (bash, dash, kornshell)? It is supposed to check if the line
variable contains any part of the path.
if [[ $line =~ "$PWD"$ ]] ;then
I just wanted to ask whether there is any command which would work on common shells (bash, dash, kornshell)? It is supposed to check if the line
variable contains any part of the path.
if [[ $line =~ "$PWD"$ ]] ;then
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 ...
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.(*"$PWD"*)
$IFS
or filename generation - an unquoted expansion will neither split nor glob.$PWD
contained a *
and was not quoted it would be construed as a pattern object and not as a literal *
to be searched for.:
comment was confusing, but I used it because it didn't gen a syntax error or accidentally run some proggie named whatever in $PATH
. This way will still gen a syntax error, but at least it's kinda clear that it should.
– mikeserv
Mar 29 '15 at 17:49
(
: case $line in *"$PWD"*)
– Stéphane Chazelas
Mar 29 '15 at 21:35
$(case a in a);; esac)
?
– Stéphane Chazelas
Mar 30 '15 at 10:22
zsh -cx '(case $1 in $2*) echo ok;;esac)' -- one o
works, but prefixing a : $
breaks it. I guess that's the problem I encountered in the past - it was always a little unclear, and I never looked at it too hard because adding the leftmost (
always fixed it. Eventually I just wrote it off as some weird zsh
thing and made it a rule to use both ends.
– mikeserv
Mar 30 '15 at 10:32
()
as well as I like to have my braces matched, but it's still worth noting that Bourne compatibility implication. Note that $(case a in a);;esac
issue used to be an issue in many shells (still is in pdksh (fixed in mksh) and ksh88 (fixed in ksh93)). I even believe it was the very reason to add support for the case string in (pattern)
variant in the case syntax in ksh in the first place.
– Stéphane Chazelas
Mar 30 '15 at 10:50
case
blocks for eval
- in the latter case it is easy enough to get lost as is. And yes, the Bourne shell compatibility requirement is certainly noteworthy, but I think your comment sums it up well enough. Thanks again. I wonder if this particular issue w/ zsh
actually is a consequence of its roots in pdksh
- isn't that where it hails from originally anyway? It is based on some pre-93 ksh
variant, I think.
– mikeserv
Mar 30 '15 at 10:55
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
/home/terdon/foo
with zsh
, ksh
and bash
(4.3.25) and it worked fine with all of them. It does indeed break when PWD
contains regex operators. That had simply never occurred to me, thanks!
– terdon
Mar 29 '15 at 22:51
=
isn't equivalent to ==
, the ==
is only supported in [[ ]]
and not [ ]
in bash. And if the pattern is a regex, you cannot always easily translate to globs.
– terdon
Feb 02 '24 at 11:16
=
first precisely because ==
is less portable, yet if I don't mention it naïve users will offer the opposite quibble. The code in original question suggested =~
but the prose of the question did not mention regex, much less require it. I'm not assuming anything about translation from regex, but rather suggesting that simply writing a glob to begin with would be simpler for the objective of "match an embedded fixed string". https://xkcd.com/1171
– Martin Kealey
Feb 04 '24 at 05:08
You can use a conditional line with shell substitution for this:
if [ "$line" != "${line#*$PWD}" ] ; then
echo "Path found in line"
fi
This works by trying to remove the value of $PWD from $line, using shell parameter expansion. If the strings don't match, then the removal was successful, and the value of $PWD was in the line (ie the $line contained $PWD).
Note however, that this may not be semantically what you want, if you are doing path matching. For example if $PWD was '/bin', and $line was '/sbin:/usr/bin' you would get a false positive match on /usr/bin (because '/bin' matches that).
This is POSIX-compliant and should work in all shells.
$PWD
; do you mean "the canonical path to the current directory"?And what do you mean by "any part of"? Any sequence of directory components? Only the leftmost components? Only the rightmost components? Any substring without regard for directory components?
– Martin Kealey Feb 02 '24 at 01:06[[ $line = *"$PWD" ]]
would work just as well. – Martin Kealey Feb 02 '24 at 01:08