bash corrispondenza globstar


17

Ho questa struttura di directory:

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

e, con l' globstaropzione abilitata in Bash, posso dire:

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

La mia domanda è: perché è dir/file.extescluso da questo elenco?

Il manuale di Bash dice questo su globstar:

Se impostato, il modello '**' utilizzato in un contesto di espansione del nome file corrisponderà a tutti i file e a zero o più directory e sottodirectory. Se il modello è seguito da un '/', corrispondono solo le directory e le sottodirectory.

" Zero " in questo paragrafo mi lascia con l'impressione che dir/file.extavrebbe dovuto essere incluso; a meno che speriamo che manchi qualcosa.


2
Cos'è questo personaggio? ɀ?
slm

2
Quale versione di bash, su quale piattaforma? Non riesco a riprodurlo con bash 4.2.37 su Debian wheezy o bash 4.1.5 su Debian squeeze. @slm unicode ɀo Wikipedia
Gilles 'SO- smetti di essere malvagio'

1
@Gilles È un prompt?
slm

5
slm, sì! ɀè solo un personaggio usato qui per distinguere il prompt. Alcuni utenti preferiscono il personaggio £o invece di $:). Inizialmente, ɀun personaggio 'z' creato per una speciale notazione in lingua africana :-)
Slyx

1
"GNU bash, versione 3.2.53 (1) -release (x86_64-apple-darwin13)" fornito con OS X 10.9 ha questo comportamento.
natevw,

Risposte:


8

Immagino che si riferisca solo al livello della sottodirectory. **senza /fiammiferi

  1. tutti i file e le directory

  2. zero o più sottodirectory

Ma non scompare del tutto. **/significa che nessun file nella directory di livello più alto a cui si **applica è associato.

Hai bisogno dir/*.ext dir/**/*.ext.


Sì, questo è esattamente il mio fallback, semplicemente non sembra carino. ;-)
Vlad GURDIGA

9

Funziona come previsto in queste versioni di Bash come fornito con le distribuzioni elencate:

  • 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

In effetti le versioni sopra elencate sono tutto ciò che ho testato. In altre parole, non ho trovato una versione 4 di Bash in cui non funziona. L'opzione è globstarstata aggiunta in Bash 4.0, vedi MODIFICHE . Nelle versioni precedenti il ​​comandoshopt -s globstar dovrebbe restituire un errore.

test

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

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

2. **/*.ext partite file.ext:

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

Preparare l'ambiente per la riproduzione dei test sopra:

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

1
Questa è la risposta esatta. L'OP ha dimenticato di impostare shopt -s globstar.
CS Pei,

4

Mi sembra che tu abbia / abbia spento globstar. Può essere attivato in questo modo:

shopt -s globstar

Non solo non corrisponderà a zero sottodirectory, ma non corrisponderà nemmeno a due sottodirectory:

$ 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

Con globstar disattivato, ** finisce per comportarsi come *, quindi dir/**/*.extottiene lo stesso risultato didir/*/*.ext

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

che a volte mi induce a pensare a globstar

controlla le tue attuali impostazioni globstar in questo modo:

shopt | grep globstar

1
È possibile controllare direttamente un'impostazione dell'opzione shell, come in shopt globstar.
Benjamin W.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.