バリエーションを含む手動の概要から、オプションのシーケンスの特定の形式を一致させるにはどうすればよいですか?

バリエーションを含む手動の概要から、オプションのシーケンスの特定の形式を一致させるにはどうすればよいですか?

これQ&Aでは、manページの概要が「大まかに」拡張バッカス・ナウア記法メタ構文記法の1つです。これは興味深いもので、背景として役立ちます。そうは言っても、関連する用語を使用すると、マニュアルのコマンド概要で見つかる最も一般的なタイプの要素の1つは、オプションシーケンス; で作られた定義リストに囲まれた開始オプションシンボルオプション終了記号. 多くの単語では、[ option ]たとえば のような単語によく関連付けられるものは、 のように、単一のダッシュまたは長い二重ダッシュの形式の後に 1 つ以上の文字が続くものになりますps --help


そこで、マニュアルでよく見かける一般的なオプションのシーケンス パターンに一致させたいと思います。

  • 始まり[と終わり]
  • オプションのシーケンスが含まれています形状または-option--option
  • 括弧の中央に必ずしも配置される必要はありません[-a]。つまり[ -ab]、、、[-abc ]すべてが一致します。
  • オプションとそのオプション要素/指定子を含むリストを許可します。[-a foo -b bar -c=biz end]
  • 外側の括弧内に他の括弧を表示できるようにします。つまり、[--a [-b[-c]] -d foo](ここでの入力全体に一致します)

... しかししない許可する:

  • ---いかなる状況でも3つのダッシュ
  • より明確に言うと、[option](ダッシュなし) や[][-][--]などは[foo-bar=a]単独では一致しません。

データには、上記の例のような異常なケースはあまり含まれていません(どのようにすればよいかわかりませんが、取引一致しない括弧でも同様ですが、これはこの記事の範囲外です。grep私が行ったように要件に対処しようとするのは、後から考えれば最善のアイデアではなかったかもしれませんが、私は次のことを試しました。

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

これは、私が望んでいることに沿ったいくつかのパターン1 に一致しますが、欠点があり、管理と再利用が困難です。一致する繰り返しを管理して「ブロック」を作成するために、任意の括弧セット (3) を使用して項目をグループ化することは、その点でも役に立ちません (ただし、デバッグには役立ちます)。入力に対応するために文字クラスを操作することは、かなり予測不可能なようです。

では、より優れた表現や異なるツール/アプローチを使用して、これをどのように行うのでしょうか。このような長い正規表現を使用する場合、どのように管理するのでしょうか。この場合、コンテンツを絞り込むためにコマンドを何度も使用する必要がありますか。そのためには、事前にコンテンツを異なる方法で操作する必要がありますか。


1.出力manpages ファイルを反復処理することで、テストを行う良い機会が得られます。ここでは grep を使用して、for i in /usr/share/man/man1/*.gz; do basename "${i//.1.gz}"; my_grep_command_above <<< "$(man -l "$i")"; donemanpages 出力全体を使用します。それ以外の場合は、man manまたはを使用すると、man asテスト用のオプション シーケンスの優れたバリエーションが提供されます。

答え1

次のようにすることができます (GNU を使用grep)。

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

質問の本文では次のようになります:

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

アイデアとしては、pcrepattern(3)ネストされた のマッチングに、で説明されているように PCRE とその再帰マッチング演算子を使用するというものです[...]

関連情報