Wie verwende ich einen erweiterten Glob mit Klammern in einem an „bash -c“ übergebenen Befehl?

Wie verwende ich einen erweiterten Glob mit Klammern in einem an „bash -c“ übergebenen Befehl?

Ich versuche, einen erweiterten Glob mit zu verwenden bash -c, habe aber keine Möglichkeit gefunden, es zum Laufen zu bringen.

Dinge, die ich versucht habe

  1. bash -c 'for f in *.!(ext); do echo $f; done'

    Ergebnis:

    bash: -c: line 0: syntax error near unexpected token `('
    

     

  2. bash -c 'for f in *.!\(ext\); do echo $f; done'

    Ergebnis:

    *.!(ext)
    

     

  3. bash -c 'for f in *.!$0; do echo $f; done' '(ext)'

    Ergebnis:

    *.!(ext)
    

     

  4. bash -c 'for f in "*.!(ext)"; do echo $f; done'

    Ergebnis:

    *.!(ext)
    

Antwort1

Um ein erweitertes Globbing-Muster in zu verwenden bash, müssen Sie die extglobShell-Option auf die eine oder andere Weise aktivieren.

Der einfachste Weg, dies für ein Inline-Skript zu tun, besteht darin, die Shell-Option mit der Option in der Befehlszeile bash -cfestzulegen :-O

bash -O extglob -c 'script code here'

Sie können auch einfach anrufenshopt -s extglob innerhalb des Skripts, aber Sie müssen sicherstellen, dass dies in einer separaten Zeile erfolgt, da sich dadurch die Art und Weise ändert, wie die Shell den Code analysiert (es ändert die Syntax der Shell):

bash -c 'shopt -s extglob
         script code here'

Und nun zu Ihrer eigentlichen Aufgabe, alle Namen auszudrucken, die nicht mit der Zeichenfolge enden .ext:

bash -O extglob -O dotglob -O nullglob -c 'printf "%s\n" !(*.ext)'

Durch zusätzliches Festlegen der Optionen dotglobund nullglobwürde das Skript mit verborgenen Namen übereinstimmen und eine einzelne leere Zeile drucken, wenn keine Übereinstimmungen vorhanden sind (anstatt das nicht erweiterte Muster zu drucken).

Beachten Sie, dass Ihr Muster *.!(ext)Dateinamen ausschließt, die auf enden ext(nicht nur auf .ext).UndDateinamen, die keinen Punkt enthalten.

verwandte Informationen