さまざまなコマンドのタブ補完を自動的に生成しようとしています。他のコマンドのマニュアルページをawkに移動し、-shortopt --long-option
各コマンドを別々の行に印刷するためにコマンドラインオプション(たとえば)を検索しました。
for (i=1;i<NF;i++){
if(match("\<-[0-9a-zA-Z_-]\+\>", $i)){
print $i
}
}
何らかの理由でこれは機能しません。単一のバックスラッシュを使用している場合、awkはエスケープシーケンスが無視され\<
リテラルとして扱われるという警告を表示します\\<
。 2つのバックスラッシュを使用すると、awkは実際に適切なパターンと一致することを拒否します(vimでマニュアルページを開き、パターンを実行すると機能するため、パターンが正しいことを前提としています)。上記のコードスニペットは私が呼び出すファイルにあるので、man {section} {page} | awk -f find-options.awk
bashとawkによってコマンド文字列が何度も解析されるという問題を排除できると思います(例:バックスラッシュ付きawk FS)awkはスクリプトファイルを直接読む必要があるからです。
答え1
man ls | col -bx | nawk '
{
for (ii=1;ii<=NF;ii++) {
if ( match($ii,/^(-[a-zA-Z0-9]|--[a-zA-Z0-9-]+)/) )
opt[substr($ii,RSTART,RLENGTH)]++
}
}
END { for (oo in opt) printf("%s\n",oo) } '
これは「新しい」awk(、、、nawk
)で機能します。mawk
gawk
変更点:
- ループ変数名の合計エラー
match()
Ed Mortonは、議論の順序が間違っていることを指摘しています。- リテラル正規表現の場合は、エスケープせずに誤った使用法を削除してください(「単語」では
/.../
なく、+
文字、数字、下線のみを使用する\<
ため、一致しません)。-
- パイプによる
col -b
バックスペース/オーバーシュートの除去 - 観察されたすべてのオプションを配列に保存して、出力の重複を抑制します。
観察されたエスケープエラーは、match()
パラメータの誤った順序によって発生します。リテラル文字列の「<」はエスケープする必要もなくしてはいけません。正規表現でのみ特別な意味を持ちます\<
(適切な/.../
区切り文字を使用)。正規表現がリテラル「文字列」または変数にある場合は、正規表現で"\\<"
リテラル文字列を使用できます。\<
これバッシュ完了パッケージには、目標と同様のタスクを実行する関数があります。_longopt
この関数はコマンドを呼び出して--help
動的に完成を生成し、最終的に次のようなものを使用します。
compgen -W "$( LC_ALL=C $COMMAND --help 2>&1 | \
sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}=\{0,1\}\).*/\1/p' | sort -u )"
次の実装を見つけることもできます(perl)。help2man
教育的には、これは「」またはそれに対応する出力を処理して、command --help
最小限のマニュアルページを生成します。
\<
¹そして\>
幅0のアサーションPOSIXではなく、現在は一般的ではなく、\b(?<=\W)
PCRE\b(?=\W)
で使用されています。gawk
これに関する記録はありませんが、GNUismをサポートしています。 Solaris ERE マッチングもサポートしていますが、そうではawk
ありません。文字列の先頭または末尾も一致する可能性があるため、期待どおりに動作します(例:use /usr/xpg4/bin/grep -E
)。
GNU awkは文字列の先頭/末尾と一致しませんが、次の単語文字と一致するように変更さ/-\<[0-9a-zA-Z_-]+\>/
れました。\<-
-\<