Warum entfernt rm * (1) * alle Dateien in einem Verzeichnis?

47

Das habe ich erwartet:

$ rm *(1)*

würde alle Dateien entfernen, die (1)im Namen enthalten sind. Ich lag falsch. Es wurden alle Dateien im Verzeichnis entfernt.

Warum?

Eric Wilson
quelle
5
Immer wenn ich rmein Muster verwende, gehe ich echodavor, bevor ich den eigentlichen Befehl gebe. Die Angewohnheit hat mich mehr als einmal gerettet (seitdem, als ich ungefähr 6 Jahre alt war, verwirrte sie den Unterschied zwischen DEL A: *.*und DEL *.* A:).
Gerrit

Antworten:

51

Von man bash:

*(pattern-list)
                 Matches zero or more occurrences of the given patterns

Sie haben einen Glob-Ausdruck, der Dateien entspricht, die mit null oder mehr 1s beginnen - das sind alle Dateien.

Eine einfache Möglichkeit, dieses Globbing-Verhalten zu deaktivieren, besteht darin \, die Klammern zu schließen:

rm *\(1\)*

Andernfalls können Sie shopt -u extglobdas Verhalten deaktivieren und shopt -s extgloberneut aktivieren:

shopt -u extglob
rm *(1)*
shopt -s extglob

Beachten Sie, dass, wie Stephane sagt , extglobdie Aktivierung durch bash-completionDeaktivieren dazu führen kann, dass die Abschlussfunktionen nicht ordnungsgemäß funktionieren.

Graeme
quelle
7
Beachten Sie, dass dies extglobnicht standardmäßig aktiviert ist, sondern von bash_completion aktiviert wird, wenn Sie dies installiert und aktiviert haben. bashhat keinen lokalen Spielraum für Optionen wie zsh.
Stéphane Chazelas
1
Beachten Sie auch, dass bash-4.3eine Regression darin besteht, dass *(1)*auch versteckte Dateien erweitert werden.
Stéphane Chazelas
@StephaneChazelas Haben Sie einen Link für den Fehler im Zusammenhang mit dieser Regression? Thanks
Basic
2
@ Basic, los geht's . Chet hat noch nicht geantwortet.
Stéphane Chazelas
9

Dies hängt wahrscheinlich mit der extglobShell-Option zusammen. Wenn ich es ausschalte, erzeugt das Muster eine Fehlermeldung:

martin@dogmeat:~$ shopt -u extglob
martin@dogmeat:~$ shopt extglob
extglob         off
martin@dogmeat:~$ echo *(1)*
bash: syntax error near unexpected token `('

Wenn ich es einschalte, scheint es tatsächlich zu allem zu passen. Die Manpage dokumentiert diese Muster, ich denke, sie hängen zusammen:

   If the extglob shell option is enabled using the shopt builtin, several
   extended  pattern  matching operators are recognized.  In the following
   description, a pattern-list is a list of one or more patterns separated
   by a |.  Composite patterns may be formed using one or more of the fol
   lowing sub-patterns:

          ?(pattern-list)
                 Matches zero or one occurrence of the given patterns
          *(pattern-list)
                 Matches zero or more occurrences of the given patterns
          +(pattern-list)
                 Matches one or more occurrences of the given patterns
          @(pattern-list)
                 Matches one of the given patterns
          !(pattern-list)
                 Matches anything except one of the given patterns

Ich sehe keine Dokumentation, die angibt, was Klammern ohne führende Zeichen tun. Wie auch immer, Sie können das Problem umgehen, indem Sie die Parens zitieren:

martin@dogmeat ~ % echo *\(1\)*
A(1)b

Verwenden Sie echooder auch ls, um Ihr Muster zuerst zu testen, wenn Sie sich nicht sicher sind, ob es funktioniert :)

Martin von Wittich
quelle
Zu Ihrer Information : {ist eine Klammer, (ist eine Klammer (oder runde Klammer).
Mikel
Ah danke. Ich bin kein englischer Muttersprachler, daher neige ich dazu, sie zu verwirren :)
Martin von Wittich
6
In britischer Sprache: {= geschweifte Klammer, (= runde Klammer, [= eckige Klammer. Auf Amerikanisch: {= Klammer, (= Paren, [= Klammer. Ein bisschen verwirrend. Wenn Sie jemals überprüfen müssen, wie etwas heißt, ist Jargon File - ASCII sehr hilfreich.
Mikel
4
@Mikel Danke, ich habe auch überprüft hier so jetzt weiß ich über Blumen Klammern und die squirrelly eine!
Im indischen Englisch {ist eine Blumenklammer [eine eckige Klammer und (ist eine runde Klammer oder häufiger nur eine Klammer. :-)
ShreevatsaR