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
Odpowiedź
Wydaje mi się, że odnosi się to tylko do poziomu podkatalogów . **
bez /
dopasowuje
-
wszystkie pliki i katalogi
-
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
.
ɀ
?unicode ɀ
lub Wikipediaɀ
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: – )