Mam taką strukturę katalogów:

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

i, z globstar opcja włączona w Bash, mogę powiedzieć:

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

Moje pytanie brzmi: dlaczego wykluczone z tej listy?

Bash manual mówi o globstar:

Jeśli jest ustawiona, wzorzec „**” użyty w kontekście rozwijania nazw plików będzie pasował do wszystkich plików oraz do zera lub większej liczby katalogów i podkatalogów. Jeśli po wzorcu występuje znak „/”, tylko katalogi i podkatalogi są zgodne.

zero ”w tym akapicie pozwolę sobie odnieść wrażenie, że dir/file.ext powinno zostać uwzględnione; chyba że mam nadzieję, że czegoś mi brakuje.

Komentarze

  • Co to za znak? ɀ?
  • Jaka wersja basha i na jakiej platformie? Nie mogę ' odtworzyć tego za pomocą bash 4.2.37 na Debianie wheezy lub bash 4.1.5 na Debian squeeze. @slm unicode ɀ lub Wikipedia
  • @Gilles Czy to podpowiedź?
  • slm, tak! ɀ to tylko znak używany tutaj do rozróżnienia monitu. Niektórzy użytkownicy wolą znak £ lub zamiast $ :). Pierwotnie ɀ a ' z ' znak utworzony dla specjalnej notacji języka afrykańskiego: – )
  • " GNU bash, wersja 3.2.53 (1) -release (x86_64-apple-darwin13) " dostarczany z OS X 10.9 ma to zachowanie.

Odpowiedź

Wydaje mi się, że odnosi się to tylko do poziomu podkatalogów . ** bez / dopasowuje

  1. wszystkie pliki i katalogi

  2. zero lub więcej podkatalogów

Ale nie znika całkowicie. **/ oznacza, że żadne pliki w katalogu najwyższego poziomu, którego dotyczy **, nie są dopasowane.

Potrzebujesz dir/*.ext dir/**/*.ext.

Komentarze

  • Tak, to jest dokładnie moja opcja zastępcza, po prostu nie wygląda ładnie. 😉

Odpowiedź

Działa to zgodnie z oczekiwaniami w tych wersjach Basha dostarczonych z wymienionymi dystrybucjami :

  • 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

W rzeczywistości wersje wymienione powyżej są wszystkim, co testowałem. Innymi słowy, nie znalazłem wersji 4 Bash, w której nie działa. Opcja globstar została dodana w Bash 4.0, patrz ZMIANY . W starszych wersjach polecenie shopt -s globstar powinno zwracać błąd.

Testy

1 . dir/**/*.ext pasuje do dir/file.ext:

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

2. **/*.ext pasuje do file.ext:

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

Przygotowanie środowiska w celu odtworzenia powyższych testów:

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

Komentarze

  • to jest poprawna odpowiedź. OP zapomniał ustawić shopt -s globstar.

Odpowiedź

I wygląda mi na to, że masz / miałaś wyłączoną globstar. Można go włączyć w ten sposób:

shopt -s globstar 

Nie tylko nie będzie pasował do żadnych podkatalogów, ale też nie będzie pasował do dwóch podkatalogów:

$ 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 

Po wyłączeniu globstar ** kończy się zachowaniem tak samo jak *, więc dir/**/*.ext otrzymuje ten sam wynik co dir/*/*.ext

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

co czasami sprawia, że myślę, że globstar jest włączony

sprawdź swoje obecne ustawienie globstar, np. to:

shopt | grep globstar 

Komentarze

  • Możesz bezpośrednio sprawdzić ustawienie opcji powłoki, tak jak w shopt globstar.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *