Neben den regulären Ausdruck basiert antwortet, können Sie dies direkt in Git, tun, die den Begriff einer „Pfadangabe“ einschließlich Shell-Stil Globbing hat:
git diff --cached --name-only \
--diff-filter=ACM -- 'local/**/*.js' 'components/**/*.js'
(Linie für die Anzeige Formatierung gebrochen, beachten Sie, dass die **
Unterstützung ist neu in Git Version 1.8.2).
Das heißt, reguläre Ausdrücke sind "leistungsfähiger" als Shell-Globs, also sollten Sie nu11p01n73R's answer im Hinterkopf behalten. Beachten Sie jedoch, dass nicht gierige Matches (*?
) Spiel als wenig wie möglich und nicht als viele wie möglich:
pattern input result (matched part in parentheses)
abc.*e 0abcdefeged 0(abcdefege)d
abc.*?e 0abcdefeged 0(abcde)feged
abc.*d 0abcdefeged 0(abcdefeged)
abc.*?d 0abcdefeged 0(abcd)efeged
Ihren Ausdruck, ^(local|components).*?.js
, sagt (in erweiterten Interpretationen sowieso): Spiel der Anfang der Linie; dann entweder local
oder components
als wörtlichen Text entsprechen; dann passen Sie so wenige Zeichen wie möglich an, vielleicht keine; dann mit einem beliebigen Zeichen übereinstimmen; dann mit einem Literal übereinstimmen j
; dann ein Literal s
übereinstimmen. Daher entspricht dies local-jaguar-xjs-vehicles
, weil es mit local
beginnt, enthält einen Text, hat ein Zeichen mehr vor js
und geht weiter.
Die Schale glob Muster local/**/*.js
Einstimmungen nur das Verzeichnis local
, von einer beliebigen Anzahl-ggf. Null-Unterverzeichnis von Komponenten, gefolgt von einem Dateinamen gefolgt, deren Enden mit .js
, mit dem Punkt buchstäblich abgestimmt. Das entspricht also dem Muster ^local/(.*/|)[^/]*\.js$
: der am Anfang der Zeile übereinstimmende Literaltext local
gefolgt von einem Schrägstrich; gefolgt von entweder: einer beliebigen Anzahl von Zeichen, die mit einem Schrägstrich enden (so viele wie möglich) oder gar nichts; gefolgt von einer beliebigen Zahl (einschließlich keine) eines beliebigen Zeichens außer Schrägstrich, gefolgt von einem Literal .js
, gefolgt vom Ende der Zeile.
Beachten Sie, dass, weil dieser Ausdruck an beiden Enden verankert ist (muss am Anfang und Ende der Leitung entsprechen), und es gibt nur eine Kleene star in der Mitte, es ist nicht, ob wir ein gierig oder nicht verwenden egal greedy match: Der linke Anker passt auf der linken Seite und der rechte Anker auf der rechten Seite, und eine gierige Übereinstimmung nimmt so viel von der Mitte wie möglich - also alles - während ein nicht-gieriges Match dauert wie wenig der Mitte, wie es kann ... was immer noch "alles davon" ist.
(Dies setzt natürlich voraus, dass die Dateinamen mit nur einer Datei pro Zeile gedruckt werden. Zum Glück git diff --name-only
tut genau das. Shell **
für "beliebig viele Verzeichnisse" wird nicht in allen Shells unterstützt. noch alle Nicht-Shell-Dateinamen globbing, aber es ist in Git verwendet pathspecs (Suche nach "pathspec").)
Ich wusste das nicht, danke! – SoluableNonagon
@SolubleNonagon Sie sind willkommen :) – nu11p01n73R