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?

Christian Cage

How to properly install USB display driver for Fresco Logic FL2000DX on Ubuntu?