14 Stimmen

Es scheint, dass das "diff"-Tool nicht über eine ausreichende Regex-Unterstützung verfügt?

Ich habe zwei Dateien, die ich mit diff vergleichen möchte. Die Dateien werden automatisch generiert und enthalten eine Reihe von Zeilen, die folgendermaßen aussehen:

//!   Generierungsdatum  : Mo, 14, Dez 2009

Ich möchte diese Unterschiede ignorieren und habe versucht, die "-I REGEX" Flagge zu verwenden, um das zu erreichen.

Die Anzahl der Leerzeichen zwischen "Datum" und dem Doppelpunkt variiert jedoch und leider scheint es, dass diff keinen Großteil der grundlegenden Regex-Utilities verwendet, die dafür nötig wären.

Ich kann zum Beispiel nicht dazu bringen, dass das "ein oder mehr" Pluszeichen funktioniert. Das Gleiche gilt für die "\s" Repräsentation von Leerzeichen.

diff -I '.*Generierungsdatum\s+:.*' ....

und

diff -I '.*Generierungsdatum +:.*' ....

scheitern beide spektakulär.

Anstatt weiter blindlings Dinge auszuprobieren, kann mir jemand eine gute Referenz zu dem diff-spezifischen Subset von regulären Ausdrücken zeigen?

Danke!

\===== BEARBEITEN =======

Dank FalseVinylShrub habe ich festgestellt, dass ich mein '+' und ähnliche Zeichen escapen sollte. Das behebt das Problem teilweise. Diff findet erfolgreich Übereinstimmungen für

.*Generierungsdatum \+.*

und

.*Generierungsdatum  *.*

(Beachten Sie, dass zwischen "Datum" und "*" zwei Leerzeichen stehen.)

Aber sobald ich versuche, den ':' zu dieser Ausdruck hinzuzufügen, wie folgt:

.*Generierungsdatum \+:.*

und

.*Generierungsdatum \+\:.*

Beide Versionen schaffen es nicht, den betreffenden String zu finden, und führen dazu, dass diff deutlich länger läuft. Irgendwelche Gedanken dazu?

0 Stimmen

Re Ihr ':' -Problem: Ich habe keine Ahnung, warum, aber versuchen Sie es (a) mit [:] zu sehen, ob das irgendwelche speziellen Effekte umgeht, obwohl der Backslash es nicht tat, oder (b) nutzen Sie ., um alles an dieser Position abzugleichen, wenn Sie sich keine Sorgen über falsche Positive machen ... nur ein Schuss ins Blaue ...

12voto

FalseVinylShrub Punkte 1203

Sehr interessant... Ich konnte keine Dokumentationsreferenz finden, aber ein wenig Experimentieren hat ergeben, dass:

  • * und .* funktionieren, wenn null oder mehr OK für dich ist
  • Wie du gesagt hast, funktioniert + nicht. Auch {1,} nicht... aber \{1,\} hat funktioniert
  • UPDATE: \+ funktioniert auch!

( stellt ein Leerzeichen dar, das nicht angezeigt wurde).

Ich benutze GNU diff von GNU diffutils 2.8.1.

man diff und info diff haben die RE-Syntax nicht erklärt.

Hoffe, das hilft.

UPDATE: Ich habe einen kurzen Abschnitt in man grep gefunden:

Normale vs Erweiterte Reguläre Ausdrücke

In normalen regulären Ausdrücken verlieren die Metazeichen ?, +, {, |, (, und ) ihre besondere Bedeutung; stattdessen verwende die rückwärts geneigten Versionen \?, \+, \{, \|, \(, und \).

Also denke ich, dass es die Basic Regex-Syntax verwendet.

0 Stimmen

Hm! Ich verwende genau die gleiche Version von GNU diff, also war das ein guter Gesundheitscheck. Ich habe mein Regex ein wenig geändert, und siehe da, du hast recht! Das Problem ist, dass es anscheinend furchtbar auf dem ":" zerfällt. Ich werde meinen ursprünglichen Beitrag bearbeiten, um das Problem zu beschreiben.

8voto

Wayne Conrad Punkte 95828

Ok, hier ist, was die Quelle von GNU diff sagt.

re_set_syntax (RE_SYNTAX_GREP | RE_NO_POSIX_BACKTRACKING);

Ich denke, das bedeutet "gleich wie gnu grep -G" (Basic Regular Expression). Laut der gnu grep Man-Seite:

In Basic Regular Expressions verlieren die Metazeichen ?, +, {, |, (und ) ihre besondere Bedeutung; stattdessen verwenden Sie die maskierten Versionen \?, \+, \{, \|, \(, und \).

Vergessen Sie \s, \S, usw.

-1voto

Jörg W Mittag Punkte 349574

Gemäß der Spezifikation unterstützt diff keine regulären Ausdrücke und verfügt auch nicht über einen -I Schalter.

Sie scheinen ein nicht standardmäßiges diff mit nicht standardmäßigen Erweiterungen zu verwenden. Wie diese nicht standardmäßigen Erweiterungen funktionieren, sollte in der Dokumentation des verwendeten nicht standardmäßigen diff beschrieben sein.

3 Stimmen

Ich verwende GNU diff 2.8.1. Ist das nicht standardmäßig?

7 Stimmen

GNU diff 2.8.1 ist eine sehr häufig verwendete Version, die von vielen GNU/*-Betriebssystemen wie Linux verwendet wird. Wenn das GNU-Toolkit nicht als Standard betrachtet werden kann, weiß ich nicht, was sonst. Siehe gnu.org/software/diffutils/manual/#Specified-Lines für die (spärlichen) Dokumente zum -I Schalter.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X