bash globstar match


18

Я маю цю структуру каталогу:

~/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. @slm unicode ɀабо Wikipedia
'SO- перестань бути злим'

1
@Gilles Це підказка?
slm

5
slm, Так! ɀце лише символ, який використовується тут для розрізнення підказки. Деякі користувачі віддають перевагу символу £або замість $:). Спочатку ɀсимвол "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.


Так, це точно мій запас, він просто не виглядає красиво. ;-)
Влад ГУРДІГА

10

Це працює так, як ви очікували в цих версіях 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

2
це правильна відповідь. ОП забула встановити shopt -s globstar.
CS Pei

5

Я дивлюся на мене так, як у вас / у вас була вимкнена глобальна зірка. Його можна ввімкнути так:

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

При вимкненому глобулі ** в кінцевому рахунку поводиться так само, як *, тому dir/**/*.extотримує такий же результат, як і *dir/*/*.ext

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

що іноді підманює мене думати про глобальну зірку

перевірте свій поточний параметр globstar таким чином:

shopt | grep globstar

1
Ви можете перевірити налаштування параметра оболонки безпосередньо, як в shopt globstar.
Бенджамін В.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.