bash globalstar phù hợp


17

Tôi có cấu trúc thư mục này:

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

và, với globstartùy chọn được bật trong Bash, tôi có thể nói:

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

Câu hỏi của tôi là: tại sao dir/file.extbị loại khỏi danh sách này?

Hướng dẫn Bash nói điều này về globstar:

Nếu được đặt, mẫu '**' được sử dụng trong ngữ cảnh mở rộng tên tệp sẽ khớp với tất cả các tệp và không hoặc nhiều thư mục và thư mục con. Nếu mẫu được theo sau bởi '/', chỉ các thư mục và thư mục con phù hợp.

Không có gì khác trong đoạn này cho tôi ấn tượng dir/file.extnên được đưa vào; trừ khi tôi hy vọng thiếu một cái gì đó


2
Nhân vật này là gì? ɀ?
slm

2
Phiên bản nào của bash, trên nền tảng nào? Tôi không thể tái tạo điều này với bash 4.2.37 trên Debian wheezy hoặc bash 4.1.5 trên Debian nén. @slm unicode ɀhoặc Wikipedia
Gilles 'SO- ngừng trở nên xấu xa'

1
@Gilles Đó có phải là một dấu nhắc?
slm

5
slm, vâng ɀchỉ là một ký tự được sử dụng ở đây để phân biệt dấu nhắc. Một số người dùng thích nhân vật £hoặc thay vì $:). Ban đầu, ɀmột ký tự 'z' được tạo cho một ký hiệu ngôn ngữ châu Phi đặc biệt :-)
Slyx

1
"GNU bash, phiên bản 3.2.53 (1) -release (x86_64-apple-darwin13)" được gửi cùng với OS X 10.9 có hành vi này.
natevw

Câu trả lời:


8

Tôi đoán rằng chỉ đề cập đến cấp thư mục con. **không có /trận đấu

  1. tất cả các tập tin và thư mục

  2. không hoặc nhiều thư mục con

Nhưng nó không hoàn toàn biến mất. **/có nghĩa là không có tệp nào trong thư mục cấp cao nhất được **áp dụng để khớp.

Bạn cần dir/*.ext dir/**/*.ext.


Vâng, đó chính xác là dự phòng của tôi, nó trông không đẹp lắm. ;-)
Vlad GURDIGA

9

Điều này hoạt động như bạn mong đợi trong các phiên bản Bash này khi được cung cấp với các bản phân phối được liệt kê:

  • 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

Trong thực tế, các phiên bản được liệt kê ở trên là tất cả những gì tôi đã thử nghiệm. Nói cách khác, tôi không tìm thấy phiên bản 4 của Bash khi nó không hoạt động. Tùy chọn globstarđã được thêm vào trong Bash 4.0, xem THAY ĐỔI . Trong các phiên bản cũ hơn, lệnh shopt -s globstarsẽ trả về lỗi.

Xét nghiệm

1. dir/**/*.ext trận đấu dir/file.ext:

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

2. **/*.ext trận đấu file.ext:

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

Chuẩn bị môi trường để tái tạo các thử nghiệm trên:

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

1
đây là câu trả lời đúng. OP quên cài đặt shopt -s globstar.
CS Pei

4

Tôi trông giống như bạn đã / đã tắt sao. Nó có thể được bật như thế này:

shopt -s globstar

Nó không chỉ không khớp với các thư mục con bằng 0, mà còn không khớp với hai thư mục con:

$ 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

Khi toàn cầu tắt, ** kết thúc giống như *, vì vậy dir/**/*.extnhận được kết quả tương tự nhưdir/*/*.ext

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

điều mà đôi khi khiến tôi nghĩ rằng sao đang ở trên

kiểm tra cài đặt sao hiện tại của bạn như thế này:

shopt | grep globstar

1
Bạn có thể kiểm tra cài đặt tùy chọn shell trực tiếp, như trong shopt globstar.
Benjamin W.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.