Alternative to Bash double bracket glob match

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












Given



hasArgs=a:b:c:
x=b
if [[ $hasArgs = *$x:* ]] ; then …


I wish I could replace the above double brackets test with a less Bash specific alternative (meaning no subshell/command etc.)



Parameter expansion does not help because it does not expend variables.



if [ "$hasArgs" != "$hasArgs#$x:" ] ; then …


Is there any simple (one line) solution that would fit this use case?







share|improve this question



















  • This is not bash specific but ksh specific. Double brackets have been introduced by ksh88.
    – schily
    Aug 3 at 22:38










  • I wanted to say POSIX compliant, but thank's I will remember where double brackets are coming from.
    – Stphane
    2 days ago










  • Double brackets have intentionally not put in to POSIX even though ksh88 was the master for the POSIX shell.
    – schily
    2 days ago
















up vote
0
down vote

favorite












Given



hasArgs=a:b:c:
x=b
if [[ $hasArgs = *$x:* ]] ; then …


I wish I could replace the above double brackets test with a less Bash specific alternative (meaning no subshell/command etc.)



Parameter expansion does not help because it does not expend variables.



if [ "$hasArgs" != "$hasArgs#$x:" ] ; then …


Is there any simple (one line) solution that would fit this use case?







share|improve this question



















  • This is not bash specific but ksh specific. Double brackets have been introduced by ksh88.
    – schily
    Aug 3 at 22:38










  • I wanted to say POSIX compliant, but thank's I will remember where double brackets are coming from.
    – Stphane
    2 days ago










  • Double brackets have intentionally not put in to POSIX even though ksh88 was the master for the POSIX shell.
    – schily
    2 days ago












up vote
0
down vote

favorite









up vote
0
down vote

favorite











Given



hasArgs=a:b:c:
x=b
if [[ $hasArgs = *$x:* ]] ; then …


I wish I could replace the above double brackets test with a less Bash specific alternative (meaning no subshell/command etc.)



Parameter expansion does not help because it does not expend variables.



if [ "$hasArgs" != "$hasArgs#$x:" ] ; then …


Is there any simple (one line) solution that would fit this use case?







share|improve this question











Given



hasArgs=a:b:c:
x=b
if [[ $hasArgs = *$x:* ]] ; then …


I wish I could replace the above double brackets test with a less Bash specific alternative (meaning no subshell/command etc.)



Parameter expansion does not help because it does not expend variables.



if [ "$hasArgs" != "$hasArgs#$x:" ] ; then …


Is there any simple (one line) solution that would fit this use case?









share|improve this question










share|improve this question




share|improve this question









asked Aug 3 at 22:26









Stphane

16917




16917











  • This is not bash specific but ksh specific. Double brackets have been introduced by ksh88.
    – schily
    Aug 3 at 22:38










  • I wanted to say POSIX compliant, but thank's I will remember where double brackets are coming from.
    – Stphane
    2 days ago










  • Double brackets have intentionally not put in to POSIX even though ksh88 was the master for the POSIX shell.
    – schily
    2 days ago
















  • This is not bash specific but ksh specific. Double brackets have been introduced by ksh88.
    – schily
    Aug 3 at 22:38










  • I wanted to say POSIX compliant, but thank's I will remember where double brackets are coming from.
    – Stphane
    2 days ago










  • Double brackets have intentionally not put in to POSIX even though ksh88 was the master for the POSIX shell.
    – schily
    2 days ago















This is not bash specific but ksh specific. Double brackets have been introduced by ksh88.
– schily
Aug 3 at 22:38




This is not bash specific but ksh specific. Double brackets have been introduced by ksh88.
– schily
Aug 3 at 22:38












I wanted to say POSIX compliant, but thank's I will remember where double brackets are coming from.
– Stphane
2 days ago




I wanted to say POSIX compliant, but thank's I will remember where double brackets are coming from.
– Stphane
2 days ago












Double brackets have intentionally not put in to POSIX even though ksh88 was the master for the POSIX shell.
– schily
2 days ago




Double brackets have intentionally not put in to POSIX even though ksh88 was the master for the POSIX shell.
– schily
2 days ago










3 Answers
3






active

oldest

votes

















up vote
2
down vote



accepted










Actually, you can use the standard parameter expansions here (you were just missing the wildcard):



$ args=a:b:c:
$ x=b
$ echo "$args%$x:*"
a:
$ if [ "$args" != "$args#*$x:" ]; then echo 'b: is present'; fi
b: is present


(or equally "$args%$x:*")



The downside is that you need to have the colon after b, so a:b or a plain b wouldn't match, and it would also match a:bb:c. ([[ $var = *$x:* ]] as well as the obvious pattern match with case have the same disadvantage.)



Matching all of b, b:c, a:b, a:b:c, while not matching a:bb:c would be a bit more tricky. All I can think of is something like this:



args=a:b:c
x=b
IFS=: # affects globally
set -f # affects globally...
for x in $args; do
if [ "$x" = "b" ]; then
echo "b is present"
fi
done


Unless you want to write all the cases out:



args=a:b:c
x=b
found=0
case "$args" in
$x) found=1;;
$x:*) found=1;;
*:$x) found=1;;
*:$x:*) found=1;;
esac
if [ "$found" = 1 ]; then ...; fi


Much easier with regexes (in Bash):



args=b:c
x=b
if [[ $args =~ (^|:)$x(:|$) ]]; then
echo "b found"
fi





share|improve this answer





















  • So (some?) parameter expansion(s) actually evaluate variables in their pattern prior to expansion, I missed the wildcard. Since there will always have a colon after the x variable, I can safely use this expression.
    – Stphane
    2 days ago







  • 1




    @Stphane, they all do, on the right hand side that takes a string, not on the left part that takes a parameter name. So, $x#$y works, but $$x#foo%bar doesn't. Except in zsh.
    – ilkkachu
    2 days ago

















up vote
6
down vote













It's not a one-liner, but this is quite readable and can be expanded to check for any number of arguments:



hasArgs="a:b:c"
x=b
case "$hasArgs" in
*$x*)
echo "$x is present"
;;
esac





share|improve this answer





















  • I should have told about this but I already use a case structure somewhere else in my script (meaning I am aware of the glob capability), this is the reason why I asked for a one-liner. But not everyone may be aware of this so your answer is surely welcome.
    – Stphane
    2 days ago

















up vote
1
down vote













The following will work in sh:



if echo "$hasArgs" | grep -q "$x"; then





share|improve this answer

















  • 2




    Congrats on 10k!
    – slm♦
    Aug 3 at 22:43










  • Looks like a good alternative to [ since both are external executables. (+ one-liner)
    – Stphane
    2 days ago











Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f460434%2falternative-to-bash-double-bracket-glob-match%23new-answer', 'question_page');

);

Post as a guest






























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










Actually, you can use the standard parameter expansions here (you were just missing the wildcard):



$ args=a:b:c:
$ x=b
$ echo "$args%$x:*"
a:
$ if [ "$args" != "$args#*$x:" ]; then echo 'b: is present'; fi
b: is present


(or equally "$args%$x:*")



The downside is that you need to have the colon after b, so a:b or a plain b wouldn't match, and it would also match a:bb:c. ([[ $var = *$x:* ]] as well as the obvious pattern match with case have the same disadvantage.)



Matching all of b, b:c, a:b, a:b:c, while not matching a:bb:c would be a bit more tricky. All I can think of is something like this:



args=a:b:c
x=b
IFS=: # affects globally
set -f # affects globally...
for x in $args; do
if [ "$x" = "b" ]; then
echo "b is present"
fi
done


Unless you want to write all the cases out:



args=a:b:c
x=b
found=0
case "$args" in
$x) found=1;;
$x:*) found=1;;
*:$x) found=1;;
*:$x:*) found=1;;
esac
if [ "$found" = 1 ]; then ...; fi


Much easier with regexes (in Bash):



args=b:c
x=b
if [[ $args =~ (^|:)$x(:|$) ]]; then
echo "b found"
fi





share|improve this answer





















  • So (some?) parameter expansion(s) actually evaluate variables in their pattern prior to expansion, I missed the wildcard. Since there will always have a colon after the x variable, I can safely use this expression.
    – Stphane
    2 days ago







  • 1




    @Stphane, they all do, on the right hand side that takes a string, not on the left part that takes a parameter name. So, $x#$y works, but $$x#foo%bar doesn't. Except in zsh.
    – ilkkachu
    2 days ago














up vote
2
down vote



accepted










Actually, you can use the standard parameter expansions here (you were just missing the wildcard):



$ args=a:b:c:
$ x=b
$ echo "$args%$x:*"
a:
$ if [ "$args" != "$args#*$x:" ]; then echo 'b: is present'; fi
b: is present


(or equally "$args%$x:*")



The downside is that you need to have the colon after b, so a:b or a plain b wouldn't match, and it would also match a:bb:c. ([[ $var = *$x:* ]] as well as the obvious pattern match with case have the same disadvantage.)



Matching all of b, b:c, a:b, a:b:c, while not matching a:bb:c would be a bit more tricky. All I can think of is something like this:



args=a:b:c
x=b
IFS=: # affects globally
set -f # affects globally...
for x in $args; do
if [ "$x" = "b" ]; then
echo "b is present"
fi
done


Unless you want to write all the cases out:



args=a:b:c
x=b
found=0
case "$args" in
$x) found=1;;
$x:*) found=1;;
*:$x) found=1;;
*:$x:*) found=1;;
esac
if [ "$found" = 1 ]; then ...; fi


Much easier with regexes (in Bash):



args=b:c
x=b
if [[ $args =~ (^|:)$x(:|$) ]]; then
echo "b found"
fi





share|improve this answer





















  • So (some?) parameter expansion(s) actually evaluate variables in their pattern prior to expansion, I missed the wildcard. Since there will always have a colon after the x variable, I can safely use this expression.
    – Stphane
    2 days ago







  • 1




    @Stphane, they all do, on the right hand side that takes a string, not on the left part that takes a parameter name. So, $x#$y works, but $$x#foo%bar doesn't. Except in zsh.
    – ilkkachu
    2 days ago












up vote
2
down vote



accepted







up vote
2
down vote



accepted






Actually, you can use the standard parameter expansions here (you were just missing the wildcard):



$ args=a:b:c:
$ x=b
$ echo "$args%$x:*"
a:
$ if [ "$args" != "$args#*$x:" ]; then echo 'b: is present'; fi
b: is present


(or equally "$args%$x:*")



The downside is that you need to have the colon after b, so a:b or a plain b wouldn't match, and it would also match a:bb:c. ([[ $var = *$x:* ]] as well as the obvious pattern match with case have the same disadvantage.)



Matching all of b, b:c, a:b, a:b:c, while not matching a:bb:c would be a bit more tricky. All I can think of is something like this:



args=a:b:c
x=b
IFS=: # affects globally
set -f # affects globally...
for x in $args; do
if [ "$x" = "b" ]; then
echo "b is present"
fi
done


Unless you want to write all the cases out:



args=a:b:c
x=b
found=0
case "$args" in
$x) found=1;;
$x:*) found=1;;
*:$x) found=1;;
*:$x:*) found=1;;
esac
if [ "$found" = 1 ]; then ...; fi


Much easier with regexes (in Bash):



args=b:c
x=b
if [[ $args =~ (^|:)$x(:|$) ]]; then
echo "b found"
fi





share|improve this answer













Actually, you can use the standard parameter expansions here (you were just missing the wildcard):



$ args=a:b:c:
$ x=b
$ echo "$args%$x:*"
a:
$ if [ "$args" != "$args#*$x:" ]; then echo 'b: is present'; fi
b: is present


(or equally "$args%$x:*")



The downside is that you need to have the colon after b, so a:b or a plain b wouldn't match, and it would also match a:bb:c. ([[ $var = *$x:* ]] as well as the obvious pattern match with case have the same disadvantage.)



Matching all of b, b:c, a:b, a:b:c, while not matching a:bb:c would be a bit more tricky. All I can think of is something like this:



args=a:b:c
x=b
IFS=: # affects globally
set -f # affects globally...
for x in $args; do
if [ "$x" = "b" ]; then
echo "b is present"
fi
done


Unless you want to write all the cases out:



args=a:b:c
x=b
found=0
case "$args" in
$x) found=1;;
$x:*) found=1;;
*:$x) found=1;;
*:$x:*) found=1;;
esac
if [ "$found" = 1 ]; then ...; fi


Much easier with regexes (in Bash):



args=b:c
x=b
if [[ $args =~ (^|:)$x(:|$) ]]; then
echo "b found"
fi






share|improve this answer













share|improve this answer



share|improve this answer











answered Aug 3 at 23:26









ilkkachu

47.3k668130




47.3k668130











  • So (some?) parameter expansion(s) actually evaluate variables in their pattern prior to expansion, I missed the wildcard. Since there will always have a colon after the x variable, I can safely use this expression.
    – Stphane
    2 days ago







  • 1




    @Stphane, they all do, on the right hand side that takes a string, not on the left part that takes a parameter name. So, $x#$y works, but $$x#foo%bar doesn't. Except in zsh.
    – ilkkachu
    2 days ago
















  • So (some?) parameter expansion(s) actually evaluate variables in their pattern prior to expansion, I missed the wildcard. Since there will always have a colon after the x variable, I can safely use this expression.
    – Stphane
    2 days ago







  • 1




    @Stphane, they all do, on the right hand side that takes a string, not on the left part that takes a parameter name. So, $x#$y works, but $$x#foo%bar doesn't. Except in zsh.
    – ilkkachu
    2 days ago















So (some?) parameter expansion(s) actually evaluate variables in their pattern prior to expansion, I missed the wildcard. Since there will always have a colon after the x variable, I can safely use this expression.
– Stphane
2 days ago





So (some?) parameter expansion(s) actually evaluate variables in their pattern prior to expansion, I missed the wildcard. Since there will always have a colon after the x variable, I can safely use this expression.
– Stphane
2 days ago





1




1




@Stphane, they all do, on the right hand side that takes a string, not on the left part that takes a parameter name. So, $x#$y works, but $$x#foo%bar doesn't. Except in zsh.
– ilkkachu
2 days ago




@Stphane, they all do, on the right hand side that takes a string, not on the left part that takes a parameter name. So, $x#$y works, but $$x#foo%bar doesn't. Except in zsh.
– ilkkachu
2 days ago












up vote
6
down vote













It's not a one-liner, but this is quite readable and can be expanded to check for any number of arguments:



hasArgs="a:b:c"
x=b
case "$hasArgs" in
*$x*)
echo "$x is present"
;;
esac





share|improve this answer





















  • I should have told about this but I already use a case structure somewhere else in my script (meaning I am aware of the glob capability), this is the reason why I asked for a one-liner. But not everyone may be aware of this so your answer is surely welcome.
    – Stphane
    2 days ago














up vote
6
down vote













It's not a one-liner, but this is quite readable and can be expanded to check for any number of arguments:



hasArgs="a:b:c"
x=b
case "$hasArgs" in
*$x*)
echo "$x is present"
;;
esac





share|improve this answer





















  • I should have told about this but I already use a case structure somewhere else in my script (meaning I am aware of the glob capability), this is the reason why I asked for a one-liner. But not everyone may be aware of this so your answer is surely welcome.
    – Stphane
    2 days ago












up vote
6
down vote










up vote
6
down vote









It's not a one-liner, but this is quite readable and can be expanded to check for any number of arguments:



hasArgs="a:b:c"
x=b
case "$hasArgs" in
*$x*)
echo "$x is present"
;;
esac





share|improve this answer













It's not a one-liner, but this is quite readable and can be expanded to check for any number of arguments:



hasArgs="a:b:c"
x=b
case "$hasArgs" in
*$x*)
echo "$x is present"
;;
esac






share|improve this answer













share|improve this answer



share|improve this answer











answered Aug 3 at 22:30









DopeGhoti

39.5k54679




39.5k54679











  • I should have told about this but I already use a case structure somewhere else in my script (meaning I am aware of the glob capability), this is the reason why I asked for a one-liner. But not everyone may be aware of this so your answer is surely welcome.
    – Stphane
    2 days ago
















  • I should have told about this but I already use a case structure somewhere else in my script (meaning I am aware of the glob capability), this is the reason why I asked for a one-liner. But not everyone may be aware of this so your answer is surely welcome.
    – Stphane
    2 days ago















I should have told about this but I already use a case structure somewhere else in my script (meaning I am aware of the glob capability), this is the reason why I asked for a one-liner. But not everyone may be aware of this so your answer is surely welcome.
– Stphane
2 days ago




I should have told about this but I already use a case structure somewhere else in my script (meaning I am aware of the glob capability), this is the reason why I asked for a one-liner. But not everyone may be aware of this so your answer is surely welcome.
– Stphane
2 days ago










up vote
1
down vote













The following will work in sh:



if echo "$hasArgs" | grep -q "$x"; then





share|improve this answer

















  • 2




    Congrats on 10k!
    – slm♦
    Aug 3 at 22:43










  • Looks like a good alternative to [ since both are external executables. (+ one-liner)
    – Stphane
    2 days ago















up vote
1
down vote













The following will work in sh:



if echo "$hasArgs" | grep -q "$x"; then





share|improve this answer

















  • 2




    Congrats on 10k!
    – slm♦
    Aug 3 at 22:43










  • Looks like a good alternative to [ since both are external executables. (+ one-liner)
    – Stphane
    2 days ago













up vote
1
down vote










up vote
1
down vote









The following will work in sh:



if echo "$hasArgs" | grep -q "$x"; then





share|improve this answer













The following will work in sh:



if echo "$hasArgs" | grep -q "$x"; then






share|improve this answer













share|improve this answer



share|improve this answer











answered Aug 3 at 22:30









Jesse_b

10.1k12658




10.1k12658







  • 2




    Congrats on 10k!
    – slm♦
    Aug 3 at 22:43










  • Looks like a good alternative to [ since both are external executables. (+ one-liner)
    – Stphane
    2 days ago













  • 2




    Congrats on 10k!
    – slm♦
    Aug 3 at 22:43










  • Looks like a good alternative to [ since both are external executables. (+ one-liner)
    – Stphane
    2 days ago








2




2




Congrats on 10k!
– slm♦
Aug 3 at 22:43




Congrats on 10k!
– slm♦
Aug 3 at 22:43












Looks like a good alternative to [ since both are external executables. (+ one-liner)
– Stphane
2 days ago





Looks like a good alternative to [ since both are external executables. (+ one-liner)
– Stphane
2 days ago













 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f460434%2falternative-to-bash-double-bracket-glob-match%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay