Bash Globstar соответствия

17

У меня есть эта структура каталогов:

~/tmp/globstar ɀ  find dir -type f
dir/file.ext
dir/subdir1/file.ext
dir/subdir2/file.ext

и с globstarвключенной опцией в Bash я могу сказать:

~/tmp/globstar ɀ  ls -1 dir/**/*.ext
dir/subdir1/file.ext
dir/subdir2/file.ext

Мой вопрос: почему dir/file.extисключен из этого списка?

Руководство Bash говорит об этом globstar:

Если установлено, шаблон '**', используемый в контексте расширения имени файла, будет соответствовать всем файлам и нулю или большему количеству каталогов и подкаталогов. Если за шаблоном следует знак «/», совпадут только каталоги и подкаталоги.

« Ноль » в этом абзаце позволил мне создать впечатление, что его dir/file.extследовало включить; если я не надеюсь что-то упустить.

Влад ГУРДИГА
источник
2
Что это за персонаж? ɀ?
SLM
2
Какая версия bash, на какой платформе? Я не могу воспроизвести это с помощью bash 4.2.37 на Debian wheezy или bash 4.1.5 на Debian squeeze. @slm unicode ɀили Википедия
Жиль "
1
@ Жиль Это подсказка?
SLM
5
да, да! ɀэто просто символ, используемый здесь, чтобы отличить подсказку. Некоторые пользователи предпочитают персонажа £или вместо $:). Первоначально, ɀсимвол 'z', созданный для специальной нотации на африканском языке :-)
Slyx
1
«GNU bash, версия 3.2.53 (1) -релиз (x86_64-apple-darwin13)», поставляемый с OS X 10.9, имеет такое поведение.
natevw

Ответы:

8

Я предполагаю, что это относится только к уровню подкаталогов. **без /спичек

  1. все файлы и каталоги

  2. ноль или более подкаталогов

Но это не исчезает полностью. **/означает, что ни один из файлов в каталоге самого высокого уровня, к которому **применяется, не сопоставлен.

Вам нужно dir/*.ext dir/**/*.ext.

Хауке Лагинг
источник
Да, это точно мой запасной вариант, он просто не выглядит красиво. ;-)
Влад ГУРДИГА
9

Это работает, как вы ожидали, в следующих версиях Bash, поставляемых со следующими дистрибутивами:

  • 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

На самом деле перечисленные выше версии - это все, что я тестировал. Другими словами, я не нашел версию 4 Bash, где она не работает. Опция globstarбыла добавлена ​​в Bash 4.0, см. ИЗМЕНЕНИЯ . В старых версиях команда shopt -s globstarдолжна возвращать ошибку.

тесты

1. dir/**/*.ext совпадения dir/file.ext:

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

2. **/*.ext совпадения file.ext:

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

Подготовка среды для воспроизведения тестов выше:

mkdir -p dir/subdir{1,2}
touch dir/{,subdir{1,2}/}file.ext
shopt -s globstar
pabouk
источник
1
это правильный ответ. ОП забыл установить shopt -s globstar.
CS Pei
4

Я смотрю на меня так, как будто ты выключил Globstar. Это может быть включено следующим образом:

shopt -s globstar

Он не только не будет соответствовать нулевым подкаталогам, но также не будет соответствовать двум подкаталогам:

$ 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

С выключенным globstar ** в конечном итоге ведет себя так же, как *, поэтому dir/**/*.extполучает тот же результат, что иdir/*/*.ext

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

что иногда заставляет меня думать, что Globstar включен

проверьте текущую настройку Globstar следующим образом:

shopt | grep globstar
Alex028502
источник
1
Вы можете проверить настройку параметров оболочки напрямую, как в shopt globstar.
Бенджамин В.