LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-26-2023, 07:09 AM   #1
jt1122
Member
 
Registered: Apr 2021
Posts: 140

Rep: Reputation: Disabled
bash extglob


from the bash extglob man page: "?(pattern-list) Matches zero or one occurrence of the given patterns"

Code:
touch a b; echo ?(a)
a
if ? matches 0 or 1 occurrences why isn't b also shown?

Thanks
 
Old 11-26-2023, 07:39 AM   #2
jkirchner
Member
 
Registered: Apr 2007
Location: West Virginia
Distribution: Pop!_OS
Posts: 945

Rep: Reputation: 297Reputation: 297Reputation: 297
In the parentheses it says "pattern list" and you gave it a pattern of "a" hence it returned "a". Try with ?(b) and you will get b.

Last edited by jkirchner; 11-26-2023 at 07:41 AM.
 
Old 11-26-2023, 09:15 AM   #3
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,035

Rep: Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344
with other words:
?(a) means either empty string or a single "a", but "b" is none of them.
Try ?(a|b) and other patterns too.
 
Old 11-26-2023, 10:36 AM   #4
jt1122
Member
 
Registered: Apr 2021
Posts: 140

Original Poster
Rep: Reputation: Disabled
"?(pattern-list) Matches zero or one occurrence of the given patterns"

The pattern "b" has 0 occurrences of "a" so based on the above it should have been returned,

Again, why isn't "b" returned?
 
Old 11-26-2023, 11:16 AM   #5
lvm_
Member
 
Registered: Jul 2020
Posts: 982

Rep: Reputation: 348Reputation: 348Reputation: 348Reputation: 348
Because glob expression matches the complete filename, not a substring. *?(a)* would match
 
Old 11-26-2023, 11:19 AM   #6
jkirchner
Member
 
Registered: Apr 2007
Location: West Virginia
Distribution: Pop!_OS
Posts: 945

Rep: Reputation: 297Reputation: 297Reputation: 297
Quote:
Originally Posted by jt1122 View Post
"?(pattern-list) Matches zero or one occurrence of the given patterns"

The pattern "b" has 0 occurrences of "a" so based on the above it should have been returned,

Again, why isn't "b" returned?
It matches against the pattern list, so there are zero return or a match, but if it "matches" it only returns matched value in the pattern. Of what purpose/value would there be if you have a list of the whole alphabet and passed it to a pattern to show only 'a' if it showed the full list anyway?

The description just says it matches against the pattern list.
 
Old 11-26-2023, 11:35 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,035

Rep: Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344
Quote:
Originally Posted by jt1122 View Post
"?(pattern-list) Matches zero or one occurrence of the given patterns"

The pattern "b" has 0 occurrences of "a" so based on the above it should have been returned,

Again, why isn't "b" returned?
because you are looking for a full match, not a partial match. The full string should match the pattern, and actually in your example there is no match.
 
Old 11-27-2023, 02:55 AM   #8
jt1122
Member
 
Registered: Apr 2021
Posts: 140

Original Poster
Rep: Reputation: Disabled
why should I care it "searches" also empty strings but returns only hits with non-empty ones?. It seems that searching "0 occurrences" makes no difference so @() = ?() and +() = *()

MWE:
Code:
touch a b aa ab ba
echo @(a|b)
a b
echo ?(a|b)
a b
so searching 0 or 1 (?) occurrences is the same as 1 (@) occurrence.

Code:
echo *(a|b)
a aa ab b ba
echo +(a|b)
a aa ab b ba
again, searching 0 or more (*) is then same as 1 or more (+) occurrences.
 
Old 11-27-2023, 03:14 AM   #9
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,035

Rep: Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344
again, it is about full match, not a partial match.
with other words: in case of a matching like this: pattern ~ sample a successful match means the pattern will/must cover the whole sample, not only a part of it.
@(a) will not match as, ab, whatever and any other strings, just a and/or empty string.

This engine (extglob) cannot do partial match, just only full match, so if you want to look for "anything else" you need to add it explicitly to the pattern. This a *, so what you are looking for is: @(a)*
Try this (too) and you will see the difference.
 
Old 11-28-2023, 05:10 AM   #10
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218
Quote:
Originally Posted by jt1122 View Post
why should I care it "searches" also empty strings but returns only hits with non-empty ones?. It seems that searching "0 occurrences" makes no difference so @() = ?() and +() = *()

MWE:
Code:
touch a b aa ab ba
echo @(a|b)
a b
echo ?(a|b)
a b
so searching 0 or 1 (?) occurrences is the same as 1 (@) occurrence.

Code:
echo *(a|b)
a aa ab b ba
echo +(a|b)
a aa ab b ba
again, searching 0 or more (*) is then same as 1 or more (+) occurrences.
The zero-or-more matches would include an empty filename - but this is not allowed.
But the following makes the difference visible:
Code:
shopt -s extglob
for pat in "*(a|b)" "+(a|b)" "?(a|b)" "@(a|b)"
do
  for x in "" a b ab bb
  do
    case $x in
    ( $pat )
      echo "$pat : '$x' matches, case-esac"
    ;;
    esac
    if [[ $x == $pat ]]
    then
      echo "$pat : '$x' matches, [[ == ]]"
    fi
  done
done

Last edited by MadeInGermany; 11-28-2023 at 05:18 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash problem : -bash: [: /bin/bash: unary operator expected J.A.X Linux - Software 1 09-22-2011 05:52 AM
$LINENO can't be modified in bash 3.0, while it can be in bash 2.05b Darwish Linux - Software 1 11-07-2005 02:57 PM
bash my little bash alaios Linux - Newbie 4 01-10-2005 11:59 PM
bash + html + javascript or just bash ? rblampain Programming 4 12-01-2004 07:53 AM
why did bash 2.05b install delete /bin/bash & "/bin/sh -> bash"? johnpipe Linux - Software 2 06-06-2004 06:42 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 05:11 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration