Bash Globstar Matching

17

Ich habe diese Verzeichnisstruktur:

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

globstarWenn die Option in Bash aktiviert ist, kann ich sagen:

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

Meine Frage ist: Warum ist dir/file.extvon dieser Liste ausgeschlossen?

Bash-Handbuch sagt dies über globstar:

Wenn festgelegt, stimmt das in einem Dateinamenerweiterungskontext verwendete Muster '**' mit allen Dateien sowie mit null oder mehr Verzeichnissen und Unterverzeichnissen überein. Wenn dem Muster ein '/' folgt, stimmen nur Verzeichnisse und Unterverzeichnisse überein.

" Null " in diesem Absatz lassen Sie mich mit dem Eindruck, der dir/file.exthätte einbezogen werden sollen; es sei denn, ich vermisse hoffentlich etwas.

Vlad GURDIGA
quelle
2
Was ist das für ein Charakter? ɀ?
slm
2
Welche Version von Bash, auf welcher Plattform? Ich kann dies nicht mit Bash 4.2.37 auf Debian Wheezy oder Bash 4.1.5 auf Debian Squeeze reproduzieren. @slm unicode ɀoder Wikipedia
Gilles '
1
@ Gilles Ist das eine Eingabeaufforderung?
SLM
5
slm, ja! ɀist nur ein Zeichen, das hier verwendet wird, um die Eingabeaufforderung zu unterscheiden. Einige Benutzer bevorzugen den Charakter £oder anstelle von $:). Ursprünglich wurde ɀein '
z'
1
"GNU bash, Version 3.2.53 (1) -Release (x86_64-apple-darwin13)", das mit OS X 10.9 ausgeliefert wurde, weist dieses Verhalten auf.
Natevw

Antworten:

8

Ich denke, das bezieht sich nur auf die Unterverzeichnisebene. **ohne /Streichhölzer

  1. alle Dateien und Verzeichnisse

  2. null oder mehr Unterverzeichnisse

Es verschwindet aber nicht ganz. **/bedeutet, dass keine Dateien in dem Verzeichnis der höchsten Ebene, auf das sich **bezieht, abgeglichen werden.

Du brauchst dir/*.ext dir/**/*.ext.

Hauke ​​Laging
quelle
Ja, das ist genau mein Fallback, es sieht einfach nicht hübsch aus. ;-)
Vlad GURDIGA
9

Dies funktioniert wie erwartet in diesen Versionen von Bash, die mit den aufgeführten Distributionen geliefert werden:

  • 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 der Tat sind die oben aufgeführten Versionen alles, was ich getestet habe. Mit anderen Worten, ich habe keine Version 4 von Bash gefunden, in der es nicht funktioniert. Die Option globstarwurde in Bash 4.0 hinzugefügt, siehe ÄNDERUNGEN . In älteren Versionen sollte der Befehl shopt -s globstareinen Fehler zurückgeben.

Tests

1. dir/**/*.ext Übereinstimmungen dir/file.ext:

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

2. **/*.ext Übereinstimmungen file.ext:

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

Vorbereiten der Umgebung für die Reproduktion der obigen Tests:

mkdir -p dir/subdir{1,2}
touch dir/{,subdir{1,2}/}file.ext
shopt -s globstar
Pabouk
quelle
1
Das ist die richtige Antwort. Das OP hat vergessen zu setzen shopt -s globstar.
CS Pei
4

Ich sehe aus, als hättest / hättest du Globstar ausgeschaltet. Es kann folgendermaßen eingeschaltet werden:

shopt -s globstar

Es werden nicht nur keine null Unterverzeichnisse gefunden, sondern auch keine zwei Unterverzeichnisse:

$ 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

Wenn globstar ausgeschaltet ist, verhält sich ** genau wie * und dir/**/*.exterhält das gleiche Ergebnis wiedir/*/*.ext

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

das bringt mich manchmal dazu zu denken, dass globstar an ist

Überprüfen Sie Ihre aktuelle Globstar-Einstellung wie folgt:

shopt | grep globstar
Alex028502
quelle
1
Sie können eine Shell-Optionseinstellung wie in direkt überprüfen shopt globstar.
Benjamin W.