Wie kann eine bestimmte Form einer optionalen Sequenz aus einer manuellen Zusammenfassung, einschließlich Variationen, abgeglichen werden?

Wie kann eine bestimmte Form einer optionalen Sequenz aus einer manuellen Zusammenfassung, einschließlich Variationen, abgeglichen werden?

InDasIn den Fragen und Antworten wird darauf hingewiesen, dass die Manpage-Synopsen "lose" auf demErweiterte Backus-Naur-Formder Metasyntaxnotation. Es ist interessant und dient als Hintergrund. Abgesehen davon ist, wenn man die entsprechende Terminologie verwendet, einer der häufigsten Elementtypen, die Sie in einer Befehlszusammenfassung aus einem Handbuch finden, deroptionale Sequenz; hergestellt aus einemDefinitionen-Listeeingeschlossen zwischen einemStartoptionssymbolund einEndoptionssymbol. In vielen Wörtern könnte etwas, das wir oft mit Dingen wie assoziieren [ option ], beispielsweise ein einzelner Bindestrich oder eine längere Doppelbindestrichform sein, gefolgt von einem oder mehreren Zeichen, wie in ps --help.


Ich möchte daher ein allgemeines optionales Sequenzmuster verwenden, das wir oft in Handbüchern sehen und das in der Tat:

  • Beginnt mit [und endet mit]
  • Enthält eine optionale Sequenz imbildenvon -optionoder--option
  • Ist nicht notwendigerweise in einer Klammer zentriert [-a], d. h [ -ab]. [-abc ]alle , , passen
  • Ermöglicht eine Liste, die eine Option und ihr optionales Element/Spezifizierer enthält, d. h.[-a foo -b bar -c=biz end]
  • Ermöglicht, dass innerhalb der äußeren Klammern andere Klammern erscheinen, d. h. [--a [-b[-c]] -d foo](würde hier mit der gesamten Eingabe übereinstimmen)

... Abernichterlauben:

  • Drei Striche ---unter allen Umständen
  • Um es klarer zu sagen: Dinge wie [option](ohne Bindestrich) und [], [-], [--]oder [foo-bar=a]allein sollten nicht übereinstimmen.

Die Daten enthalten nicht allzu viele ungewöhnliche Fälle wie die oben dargestellten Beispiele (ich wüsste nicht, wie ichhandelnauch mit nicht übereinstimmenden Klammern, aber das geht über den Rahmen dieses Artikels hinaus). Der Versuch, die Anforderungen mit grepso zu erfüllen, wie ich es getan habe, war im Nachhinein vielleicht nicht die beste Idee, aber ich habe es versucht:

grep -E '\[{1,}([[:space:]]{0,}[[:punct:]]{0,}[[:alnum:]]{0,}){0,}(-{1,2}[[:alpha:]]{1,}){1,}([[:alnum:]]{0,}[[:punct:]]{0,}[[:space:]]{0,}){0,}\]{1,}'

Es entspricht einigen Mustern 1 , in etwa dem, was ich will, aber es hat Mängel, ist schwer zu verwalten und wiederzuverwenden. Die Verwendung beliebiger Klammern (3) zum Gruppieren von Elementen, um übereinstimmende Wiederholungen zu verwalten und „Blöcke“ zu erstellen, hilft in dieser Hinsicht auch nicht (hilft aber beim Debuggen). Das Spielen mit Zeichenklassen, um die Eingabe zu berücksichtigen, scheint ziemlich unvorhersehbar.

Wie macht man das also mit einem besseren Ausdruck und/oder einem anderen Tool/Ansatz? Wie geht man mit so langen regulären Ausdrücken um, wenn man sie verwendet – muss man in diesem Fall einen Befehl mehrmals verwenden, um den Inhalt herauszufiltern? Muss ich den Inhalt vorher anders bearbeiten, um mir dabei zu helfen?


1. DieAusgabeDas Durchlaufen der Manpage-Dateien bietet eine gute Testmöglichkeit. Mit grep habe ich hier Folgendes verwendet: for i in /usr/share/man/man1/*.gz; do basename "${i//.1.gz}"; my_grep_command_above <<< "$(man -l "$i")"; doneunter Verwendung der gesamten Manpage-Ausgabe. Andernfalls bietet man manoder man aseine gute Auswahl an optionalen Sequenzen zum Testen.

Antwort1

Sie könnten (mit GNU grep) Folgendes tun:

grep -Po '\[\s*--?(?!-)((?>[^][]+)|\[(?1)*\])+\]'

Was im Text Ihrer Frage steht:

[-a]
[ -ab]
[-abc ]
[-a foo -b bar -c=biz end]
[--a [-b[-c]] -d foo]

pcrepattern(3)Die Idee besteht darin, PCRE und seine rekursiven Matching-Operatoren wie unter zum Abgleichen verschachtelter Werte beschrieben zu verwenden [...].

verwandte Informationen