bash globstar matching

This works as you expected in these versions of Bash as supplied with the listed distributions:

  • 4.1.2(1) — CentOS 6.5
  • 4.1.5(1) — Debian 6.0.10
  • 4.1.10(4) — Cygwin 1.7.31
  • 4.2.46(1) — CentOS 7.1
  • 4.3.11(1) — Ubuntu 14.04.1
  • 4.3.30(1) — Debian 8.1

In fact the versions listed above are all that I tested. In other words I did not find a version 4 of Bash where it does not work. The option globstar was added in Bash 4.0 see CHANGES. In older versions the command shopt -s globstar should return an error.

Tests

1. dir/**/*.ext matches dir/file.ext:

~/tests$ ls -1 dir/**/*.ext
dir/file.ext
dir/subdir1/file.ext
dir/subdir2/file.ext

2. **/*.ext matches file.ext:

~/tests$ cd dir
~/tests/dir$ ls -1 **/*.ext
file.ext
subdir1/file.ext
subdir2/file.ext

Preparing the environment for reproducing the tests above:

mkdir -p dir/subdir{1,2}
touch dir/{,subdir{1,2}/}file.ext
shopt -s globstar

I guess that refers to the subdirectory level only. ** without / matches

  1. all files and directories

  2. zero or more subdirectories

But it does not completely disappear. **/ means that no files in the highest-level directory which ** applies to are matched.

You need dir/*.ext dir/**/*.ext.


I looks to me like you have/had globstar turned off. It can be turned on on like this:

shopt -s globstar

Not only will it not match zero subdirectories, but it won't match two subdirectories either:

$ find dir -type f #the same as yours except with a directory inside one of the subdirectories
dir/file.ext
dir/subdir1/file.ext
dir/subdir1/subsubdir/file.ext
dir/subdir2/file.ext
$ shopt -u globstar #turn globstar off
$ #will only show files in subdirectories
$ #will not show files in dir or in subsubdir
$ echo dir/**/*.ext
dir/subdir1/file.ext dir/subdir2/file.ext
$ shopt -s globstar #turn globstar on
$ #will show all four files
$ echo dir/**/*.ext
dir/file.ext dir/subdir1/file.ext dir/subdir1/subsubdir/file.ext dir/subdir2/file.ext

With globstar off, ** ends up behaving just like *, so dir/**/*.ext gets the same result as dir/*/*.ext

$ echo dir/*/*.ext
dir/subdir1/file.ext dir/subdir2/file.ext

which sometimes tricks me into thinking globstar is on

check your current globstar setting like this:

shopt | grep globstar

Tags:

Bash

Wildcards