bash pencocokan globstar

17

Saya memiliki struktur direktori ini:

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

dan, dengan globstaropsi yang diaktifkan di Bash, saya dapat mengatakan:

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

Pertanyaan saya adalah: mengapa dir/file.extdikecualikan dari daftar ini?

Bash manual mengatakan ini tentang globstar:

Jika diatur, pola '**' yang digunakan dalam konteks ekspansi nama file akan cocok dengan semua file dan nol atau lebih direktori dan subdirektori. Jika polanya diikuti oleh '/', hanya direktori dan subdirektori yang cocok.

" Nol " dalam paragraf ini izinkan saya dengan kesan yang dir/file.extseharusnya dimasukkan; kecuali saya mudah-mudahan kehilangan sesuatu.

Vlad GURDIGA
sumber
2
Karakter apa ini? ɀ?
slm
2
Versi bash apa, di platform apa? Saya tidak dapat mereproduksi ini dengan bash 4.2.37 pada Debian wheezy atau bash 4.1.5 pada Debian squeeze. @slm unicode ɀatau Wikipedia
Gilles 'SO- stop being evil'
1
@ Gilles Apakah itu bisikan?
slm
5
slm, ya! ɀhanyalah karakter yang digunakan di sini untuk membedakan prompt. Beberapa pengguna lebih suka karakter £atau bukannya $:). Awalnya, ɀkarakter 'z' dibuat untuk notasi bahasa khusus Afrika :-)
Slyx
1
"GNU bash, versi 3.2.53 (1) -release (x86_64-apple-darwin13)" yang dikirimkan dengan OS X 10.9 memiliki perilaku ini.
natevw

Jawaban:

8

Saya kira itu merujuk pada level subdirektori saja. **tanpa /korek api

  1. semua file dan direktori

  2. nol atau lebih subdirektori

Tapi itu tidak sepenuhnya hilang. **/berarti tidak ada file dalam direktori level tertinggi yang **berlaku untuk dicocokkan.

Kamu butuh dir/*.ext dir/**/*.ext.

Hauke ​​Laging
sumber
Ya, itulah mundur saya, tidak terlihat cantik. ;-)
Vlad GURDIGA
9

Ini berfungsi seperti yang Anda harapkan dalam versi Bash ini sebagaimana disertakan dengan distribusi yang terdaftar:

  • 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

Sebenarnya versi yang tercantum di atas adalah semua yang saya uji. Dengan kata lain saya tidak menemukan versi 4 dari Bash yang tidak berfungsi. Opsi globstarditambahkan di Bash 4.0 lihat PERUBAHAN . Dalam versi yang lebih lama perintahnyashopt -s globstar harus mengembalikan kesalahan.

Tes

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

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

2. **/*.ext cocok file.ext:

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

Mempersiapkan lingkungan untuk mereproduksi tes di atas:

mkdir -p dir/subdir{1,2}
touch dir/{,subdir{1,2}/}file.ext
shopt -s globstar
pabouk
sumber
1
Ini adalah jawaban yang benar. OP lupa mengatur shopt -s globstar.
CS Pei
4

Saya melihat Anda seperti Anda telah / telah mematikan globstar. Ini bisa dihidupkan seperti ini:

shopt -s globstar

Tidak hanya itu tidak cocok dengan nol subdirektori, tetapi juga tidak akan cocok dengan dua subdirektori:

$ 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

Dengan globstar off, ** akhirnya berperilaku seperti *, jadi dir/**/*.extdapatkan hasil yang sama dengandir/*/*.ext

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

yang terkadang menipu saya untuk berpikir bahwa globstar aktif

periksa pengaturan globstar Anda saat ini seperti ini:

shopt | grep globstar
Alex028502
sumber
1
Anda dapat memeriksa pengaturan opsi shell secara langsung, seperti pada shopt globstar.
Benjamin W.