What does `.[].foo[]` do in bash? Why does it match `..`?
Clash Royale CLAN TAG#URR8PPP
up vote
16
down vote
favorite
Look at the following:
$ echo ..aliases
..
$ echo ..foo
..
$ echo ..
..
$ echo ..xyz
..
$ echo .xyz.xyz
.xyz.xyz
$ echo .xyz.
.xyz.
Apparently this seems to be globbing something, but I donâÂÂt understand how the result comes together. From my understanding is an empty character class. It would be intuitive if
- it matched only the empty string; in this case, IâÂÂd expect bash to reproduce in its entirety since nothing matches it in this directory, but also match things like
..aliases
(in the first example), - or nothing at all; in this case, IâÂÂd expect bash to reproduce the string in total, too.
This is with GNU bash, version 4.4.23(1)-release.
bash shell wildcards
add a comment |Â
up vote
16
down vote
favorite
Look at the following:
$ echo ..aliases
..
$ echo ..foo
..
$ echo ..
..
$ echo ..xyz
..
$ echo .xyz.xyz
.xyz.xyz
$ echo .xyz.
.xyz.
Apparently this seems to be globbing something, but I donâÂÂt understand how the result comes together. From my understanding is an empty character class. It would be intuitive if
- it matched only the empty string; in this case, IâÂÂd expect bash to reproduce in its entirety since nothing matches it in this directory, but also match things like
..aliases
(in the first example), - or nothing at all; in this case, IâÂÂd expect bash to reproduce the string in total, too.
This is with GNU bash, version 4.4.23(1)-release.
bash shell wildcards
add a comment |Â
up vote
16
down vote
favorite
up vote
16
down vote
favorite
Look at the following:
$ echo ..aliases
..
$ echo ..foo
..
$ echo ..
..
$ echo ..xyz
..
$ echo .xyz.xyz
.xyz.xyz
$ echo .xyz.
.xyz.
Apparently this seems to be globbing something, but I donâÂÂt understand how the result comes together. From my understanding is an empty character class. It would be intuitive if
- it matched only the empty string; in this case, IâÂÂd expect bash to reproduce in its entirety since nothing matches it in this directory, but also match things like
..aliases
(in the first example), - or nothing at all; in this case, IâÂÂd expect bash to reproduce the string in total, too.
This is with GNU bash, version 4.4.23(1)-release.
bash shell wildcards
Look at the following:
$ echo ..aliases
..
$ echo ..foo
..
$ echo ..
..
$ echo ..xyz
..
$ echo .xyz.xyz
.xyz.xyz
$ echo .xyz.
.xyz.
Apparently this seems to be globbing something, but I donâÂÂt understand how the result comes together. From my understanding is an empty character class. It would be intuitive if
- it matched only the empty string; in this case, IâÂÂd expect bash to reproduce in its entirety since nothing matches it in this directory, but also match things like
..aliases
(in the first example), - or nothing at all; in this case, IâÂÂd expect bash to reproduce the string in total, too.
This is with GNU bash, version 4.4.23(1)-release.
bash shell wildcards
bash shell wildcards
edited Aug 14 at 10:46
Jeff Schaller
32.4k849110
32.4k849110
asked Aug 11 at 16:16
Jonas Schäfer
8441722
8441722
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
25
down vote
accepted
The [
starts a set. A set is terminated by ]
. But there is a way to have ]
as part of the set, and that is to specify the ]
as the first character. As an empty set doesn't make any sense, this is not ambiguous.
So your examples are basically all a dot followed by a set that contains a dot, therefore it matches two dots.
The later examples don't find any files and are therefore returned verbatim.
add a comment |Â
up vote
4
down vote
Only quoted strings are not subject to globbing:
$ echo "..aliases"
..aliases
But un-quoted strings are subject to globbing. An unquoted string that contains an *
or a ?
or (valid) (bracket expression) will be modified by the list of files that match it. In the same way as a
*
will transform into all the files in the matching directory and a ?
will match files of only one character, a (valid) will match files with the characters inside the brackets. A dot is a valid character:
$ echo a[.]b
a[.]b
$ touch "a.b"
$ echo a[.]b
a.b
To be able to match a ]
it should be the first character inside the brackets:
$ touch "a]b"
$ ls a]b
a]b
An empty bracket expression makes no sense (and is not expanded):
$ touch ab
$ ls ab
ls: cannot access 'ab': No such file or directory
That is why this works:
$ touch a]c abc afc azc a:c a?c aoc
$ ls abfz:?]c
abc a:c a?c a]c afc azc
For [
the idea is similar:
$ touch a[c
$ ls a[c
a[c
but it could be at any position in a bracket expression:
$ ls abf[z:?]c
abc a:c a?c a[c a]c afc azc
$ ls abfz:?c
abc a:c a?c a[c a]c afc azc
The string you posted ..foo
will match a dot followed by either a ]
, a .
, a f
, a o
or a [
. It is similar to:
$ echo a.fooc
a[c a]c afc aoc
And it will match as follows:
$ touch .] .f .o .[ .a .b .z
$ echo ..foo
.. .[ .] .f .o
Note that the directory entry ..
does not need to be created as it exists inside every directory by default. But a simple dot .
wonâÂÂt be matched by a glob as it needs to be matched explicitly (by actually using a dot).
But that will not match ..aliases
as the bracket expression will only match one character. To match several characters you need to use a *
(anything):
$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo ..aliases
.. .[ .] .a
$ echo ..aliases*
.. .[ .] .a ..a ..ali ..alias ..aliases ..i ..l
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
25
down vote
accepted
The [
starts a set. A set is terminated by ]
. But there is a way to have ]
as part of the set, and that is to specify the ]
as the first character. As an empty set doesn't make any sense, this is not ambiguous.
So your examples are basically all a dot followed by a set that contains a dot, therefore it matches two dots.
The later examples don't find any files and are therefore returned verbatim.
add a comment |Â
up vote
25
down vote
accepted
The [
starts a set. A set is terminated by ]
. But there is a way to have ]
as part of the set, and that is to specify the ]
as the first character. As an empty set doesn't make any sense, this is not ambiguous.
So your examples are basically all a dot followed by a set that contains a dot, therefore it matches two dots.
The later examples don't find any files and are therefore returned verbatim.
add a comment |Â
up vote
25
down vote
accepted
up vote
25
down vote
accepted
The [
starts a set. A set is terminated by ]
. But there is a way to have ]
as part of the set, and that is to specify the ]
as the first character. As an empty set doesn't make any sense, this is not ambiguous.
So your examples are basically all a dot followed by a set that contains a dot, therefore it matches two dots.
The later examples don't find any files and are therefore returned verbatim.
The [
starts a set. A set is terminated by ]
. But there is a way to have ]
as part of the set, and that is to specify the ]
as the first character. As an empty set doesn't make any sense, this is not ambiguous.
So your examples are basically all a dot followed by a set that contains a dot, therefore it matches two dots.
The later examples don't find any files and are therefore returned verbatim.
edited Aug 11 at 18:25
Jeff Schaller
32.4k849110
32.4k849110
answered Aug 11 at 16:20
RalfFriedl
3,6401522
3,6401522
add a comment |Â
add a comment |Â
up vote
4
down vote
Only quoted strings are not subject to globbing:
$ echo "..aliases"
..aliases
But un-quoted strings are subject to globbing. An unquoted string that contains an *
or a ?
or (valid) (bracket expression) will be modified by the list of files that match it. In the same way as a
*
will transform into all the files in the matching directory and a ?
will match files of only one character, a (valid) will match files with the characters inside the brackets. A dot is a valid character:
$ echo a[.]b
a[.]b
$ touch "a.b"
$ echo a[.]b
a.b
To be able to match a ]
it should be the first character inside the brackets:
$ touch "a]b"
$ ls a]b
a]b
An empty bracket expression makes no sense (and is not expanded):
$ touch ab
$ ls ab
ls: cannot access 'ab': No such file or directory
That is why this works:
$ touch a]c abc afc azc a:c a?c aoc
$ ls abfz:?]c
abc a:c a?c a]c afc azc
For [
the idea is similar:
$ touch a[c
$ ls a[c
a[c
but it could be at any position in a bracket expression:
$ ls abf[z:?]c
abc a:c a?c a[c a]c afc azc
$ ls abfz:?c
abc a:c a?c a[c a]c afc azc
The string you posted ..foo
will match a dot followed by either a ]
, a .
, a f
, a o
or a [
. It is similar to:
$ echo a.fooc
a[c a]c afc aoc
And it will match as follows:
$ touch .] .f .o .[ .a .b .z
$ echo ..foo
.. .[ .] .f .o
Note that the directory entry ..
does not need to be created as it exists inside every directory by default. But a simple dot .
wonâÂÂt be matched by a glob as it needs to be matched explicitly (by actually using a dot).
But that will not match ..aliases
as the bracket expression will only match one character. To match several characters you need to use a *
(anything):
$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo ..aliases
.. .[ .] .a
$ echo ..aliases*
.. .[ .] .a ..a ..ali ..alias ..aliases ..i ..l
add a comment |Â
up vote
4
down vote
Only quoted strings are not subject to globbing:
$ echo "..aliases"
..aliases
But un-quoted strings are subject to globbing. An unquoted string that contains an *
or a ?
or (valid) (bracket expression) will be modified by the list of files that match it. In the same way as a
*
will transform into all the files in the matching directory and a ?
will match files of only one character, a (valid) will match files with the characters inside the brackets. A dot is a valid character:
$ echo a[.]b
a[.]b
$ touch "a.b"
$ echo a[.]b
a.b
To be able to match a ]
it should be the first character inside the brackets:
$ touch "a]b"
$ ls a]b
a]b
An empty bracket expression makes no sense (and is not expanded):
$ touch ab
$ ls ab
ls: cannot access 'ab': No such file or directory
That is why this works:
$ touch a]c abc afc azc a:c a?c aoc
$ ls abfz:?]c
abc a:c a?c a]c afc azc
For [
the idea is similar:
$ touch a[c
$ ls a[c
a[c
but it could be at any position in a bracket expression:
$ ls abf[z:?]c
abc a:c a?c a[c a]c afc azc
$ ls abfz:?c
abc a:c a?c a[c a]c afc azc
The string you posted ..foo
will match a dot followed by either a ]
, a .
, a f
, a o
or a [
. It is similar to:
$ echo a.fooc
a[c a]c afc aoc
And it will match as follows:
$ touch .] .f .o .[ .a .b .z
$ echo ..foo
.. .[ .] .f .o
Note that the directory entry ..
does not need to be created as it exists inside every directory by default. But a simple dot .
wonâÂÂt be matched by a glob as it needs to be matched explicitly (by actually using a dot).
But that will not match ..aliases
as the bracket expression will only match one character. To match several characters you need to use a *
(anything):
$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo ..aliases
.. .[ .] .a
$ echo ..aliases*
.. .[ .] .a ..a ..ali ..alias ..aliases ..i ..l
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Only quoted strings are not subject to globbing:
$ echo "..aliases"
..aliases
But un-quoted strings are subject to globbing. An unquoted string that contains an *
or a ?
or (valid) (bracket expression) will be modified by the list of files that match it. In the same way as a
*
will transform into all the files in the matching directory and a ?
will match files of only one character, a (valid) will match files with the characters inside the brackets. A dot is a valid character:
$ echo a[.]b
a[.]b
$ touch "a.b"
$ echo a[.]b
a.b
To be able to match a ]
it should be the first character inside the brackets:
$ touch "a]b"
$ ls a]b
a]b
An empty bracket expression makes no sense (and is not expanded):
$ touch ab
$ ls ab
ls: cannot access 'ab': No such file or directory
That is why this works:
$ touch a]c abc afc azc a:c a?c aoc
$ ls abfz:?]c
abc a:c a?c a]c afc azc
For [
the idea is similar:
$ touch a[c
$ ls a[c
a[c
but it could be at any position in a bracket expression:
$ ls abf[z:?]c
abc a:c a?c a[c a]c afc azc
$ ls abfz:?c
abc a:c a?c a[c a]c afc azc
The string you posted ..foo
will match a dot followed by either a ]
, a .
, a f
, a o
or a [
. It is similar to:
$ echo a.fooc
a[c a]c afc aoc
And it will match as follows:
$ touch .] .f .o .[ .a .b .z
$ echo ..foo
.. .[ .] .f .o
Note that the directory entry ..
does not need to be created as it exists inside every directory by default. But a simple dot .
wonâÂÂt be matched by a glob as it needs to be matched explicitly (by actually using a dot).
But that will not match ..aliases
as the bracket expression will only match one character. To match several characters you need to use a *
(anything):
$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo ..aliases
.. .[ .] .a
$ echo ..aliases*
.. .[ .] .a ..a ..ali ..alias ..aliases ..i ..l
Only quoted strings are not subject to globbing:
$ echo "..aliases"
..aliases
But un-quoted strings are subject to globbing. An unquoted string that contains an *
or a ?
or (valid) (bracket expression) will be modified by the list of files that match it. In the same way as a
*
will transform into all the files in the matching directory and a ?
will match files of only one character, a (valid) will match files with the characters inside the brackets. A dot is a valid character:
$ echo a[.]b
a[.]b
$ touch "a.b"
$ echo a[.]b
a.b
To be able to match a ]
it should be the first character inside the brackets:
$ touch "a]b"
$ ls a]b
a]b
An empty bracket expression makes no sense (and is not expanded):
$ touch ab
$ ls ab
ls: cannot access 'ab': No such file or directory
That is why this works:
$ touch a]c abc afc azc a:c a?c aoc
$ ls abfz:?]c
abc a:c a?c a]c afc azc
For [
the idea is similar:
$ touch a[c
$ ls a[c
a[c
but it could be at any position in a bracket expression:
$ ls abf[z:?]c
abc a:c a?c a[c a]c afc azc
$ ls abfz:?c
abc a:c a?c a[c a]c afc azc
The string you posted ..foo
will match a dot followed by either a ]
, a .
, a f
, a o
or a [
. It is similar to:
$ echo a.fooc
a[c a]c afc aoc
And it will match as follows:
$ touch .] .f .o .[ .a .b .z
$ echo ..foo
.. .[ .] .f .o
Note that the directory entry ..
does not need to be created as it exists inside every directory by default. But a simple dot .
wonâÂÂt be matched by a glob as it needs to be matched explicitly (by actually using a dot).
But that will not match ..aliases
as the bracket expression will only match one character. To match several characters you need to use a *
(anything):
$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo ..aliases
.. .[ .] .a
$ echo ..aliases*
.. .[ .] .a ..a ..ali ..alias ..aliases ..i ..l
edited Aug 19 at 14:06
Jeff Schaller
32.4k849110
32.4k849110
answered Aug 11 at 22:37
Isaac
7,0321834
7,0321834
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f462017%2fwhat-does-foo-do-in-bash-why-does-it-match%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password