
我正在嘗試提取所有指令概要從/usr/share/man/man1
使用手冊頁:
#!/usr/bin/env bash
## synopses - extract all synopses in /usr/share/man/man1
cd /usr/share/man/man1
for i in *.gz; do
echo "$i:" | sed -E "s/.1.gz|.gz//g"
man "./$i" | sed -n '/^SYNOPSIS/,/^[A-Z][A-Z][A-Z]/p' | sed -e '1d; $d' | tr -s [:space:]
done
....這提供了一些成功的衡量標準 - 我從以下位置獲得命令的完整輸出A到z。但我也遇到了很多錯誤標準錯誤同時使用for i in ./*.gz; do man "$i"
和for i in *.gz; do man "./$i"
當我輸出到文件時( synopses > file
) 1 :
<standard input>:27: expected `;' after scale-indicator (got `o')
<standard input>:29: expected `;' after scale-indicator (got `o')
<standard input>:283: name expected (got `\{'): treated as missing
<standard input>:674: warning: macro `as',' not defined (possibly missing space after `as')
<standard input>:174: name expected (got `\{'): treated as missing
<standard input>:161: warning [p 1, 5.5i]: can't break line
<standard input>:594: warning [p 5, 3.8i, div `an-div', 0.0i]: can't break line
<standard input>:569: warning [p 6, 0.0i]: can't break line
<standard input>:147: warning [p 1, 1.8i]: can't break line
<standard input>:205: warning [p 2, 0.2i]: can't break line
<standard input>:525: warning [p 5, 4.5i]: can't break line
<standard input>:157: warning [p 1, 4.8i]: can't break line
<standard input>:351: warning [p 3, 1.8i, div `an-div', 0.0i]: can't break line
<standard input>:147: a space character is not allowed in an escape name
man: can't open man1/zshmisc.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshexpn.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshparam.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshoptions.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshbuiltins.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshzle.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshcompwid.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshcompsys.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshcompctl.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshmodules.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshcalsys.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshtcpsys.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshzftpsys.1: No such file or directory
man: -:423: warning: failed .so request
man: can't open man1/zshcontrib.1: No such file or directory
man: -:423: warning: failed .so request
<standard input>:423: can't open `man1/zshmisc.1': No such file or directory
<standard input>:424: can't open `man1/zshexpn.1': No such file or directory
<standard input>:425: can't open `man1/zshparam.1': No such file or directory
<standard input>:426: can't open `man1/zshoptions.1': No such file or directory
<standard input>:427: can't open `man1/zshbuiltins.1': No such file or directory
<standard input>:428: can't open `man1/zshzle.1': No such file or directory
<standard input>:429: can't open `man1/zshcompwid.1': No such file or directory
<standard input>:430: can't open `man1/zshcompsys.1': No such file or directory
<standard input>:431: can't open `man1/zshcompctl.1': No such file or directory
<standard input>:432: can't open `man1/zshmodules.1': No such file or directory
<standard input>:433: can't open `man1/zshcalsys.1': No such file or directory
<standard input>:434: can't open `man1/zshtcpsys.1': No such file or directory
<standard input>:435: can't open `man1/zshzftpsys.1': No such file or directory
<standard input>:436: can't open `man1/zshcontrib.1': No such file or directory
這些<standard input>
錯誤是什麼(逃逸的東西?)以及為什麼man
最終找不到一些文件?我怎樣才能使其更加穩健/高效?
1. 似乎有錯誤標準錯誤無論我對相同數據使用何種實現/解決方案,它們都是相同的。這是驚人的。
答案1
你不能只是跑看起來像你能運行man foo.gz
man foo.1.gz
但使用-l
似乎更乾淨。從man man
:
-l, --local-file
Activate `local' mode. Format and display local manual files
instead of searching through the system's manual collection.
Each manual page argument will be interpreted as an nroff source
file in the correct format. No cat file is produced. If '-' is
listed as one of the arguments, input will be taken from stdin.
When this option is not used, and man fails to find the page
required, before displaying the error message, it attempts to
act as if this option was supplied, using the name as a filename
and looking for an exact match.
所以,你的腳本應該是這樣的:
#!/usr/bin/env bash
## synopses - extract all synopses in /usr/share/man/man1
## No need to cd into the directory, you can just use globs
for i in /usr/share/man/man1/ajc*.gz; do
## This will print the name of the command.
basename "${i//.1.gz}"
man -l "$i" |
awk '/^SYNOPSIS/{a=1; getline}
(/^[a-zA-z0-9_]/ && a==1){a=0}
(a==1 && /./){print}' | tr -s [:space:]
done
我給出的命令awk
比您的方法效果更好(例如對其進行測試man ajc
),現在也適用於多行概要。您看到的大多數錯誤都是無關緊要的,其他錯誤是由於您處理檔案名稱的方式造成的。讓我知道這個效果是否更好。
答案2
關於您遇到的錯誤,這些都在這裡解決:
man man
MANWIDTH
- 如果$MANWIDTH
設置,則其值用作手冊頁應格式化的行長度。如果未設定,則手冊頁將採用適合當前終端的行長度進行格式化(如果可用,則使用 ioctl(2)、 的值$COLUMNS
,或者如果兩者都不可用,則回退到 80 個字元)。只有當可以使用預設格式時,即終端行長度在 66 到 80 個字元之間時,才會儲存 Cat 頁面。
MAN_KEEP_FORMATTING
- 通常,當輸出未定向到終端(例如檔案或管道)時,格式字元將被丟棄,以便無需特殊工具即可輕鬆讀取結果。但是,如果$MAN_KEEP_FORMATTING
設定為任何非空值,則保留這些格式字元。這對於能夠解釋格式化字元的 man 包裝器可能很有用。
MAN_KEEP_STDERR
- 通常,當輸出定向到終端(通常是尋呼機)時,用於產生手冊頁格式化版本的命令的任何錯誤輸出都將被丟棄,以避免干擾尋呼機的顯示。諸如此類的程式groff
經常會產生有關印刷問題(例如對齊不良)的相對較小的錯誤訊息,這些錯誤訊息與手冊頁一起顯示時既難看又通常令人困惑。但是,有些用戶無論如何都想看到它們,因此,如果$MAN_KEEP_STDERR
設定為任何非空值,錯誤輸出將照常顯示。
現在關於如何做另一件事:
我認為這符合你的要求:
for f in /usr/share/man/man1/*gz ; do
man -P "sed -ne '1,/^[Nn]/d;/^ /{H;b}
/^[Ss]..[Yy]..[Nn]/{g;:n
N;/\n\(\n\)[^ ].*/!bn;s//\1/
s/.\x08//g;s/\(\n\) */\1/g;
w /dev/stderr' -ne '};/./q'" -l "$f"
done 2>~/file
它指定是sed
然後PAGER
僅輸出下面的行姓名以及以下人員概要直到它遇到任何以 a 以外的內容開頭的行<space>
。它列印沒有什麼如果第一行不是以<space>
下面的開頭姓名不符合 begin [Ss][Yy][Nn]
。在每種情況下,它都會在遇到以下情況的第二行完全停止讀取文件姓名不以 開頭<space>
。它從輸出中清除前導斜線<spaces>
和所有反斜線。\b
我for
剛剛在循環中運行了它,它只man
用了一分鐘就遍歷了我的整個庫。
man
根據是否寫入終端機或管道/檔案來調整其輸出。因此,如果你告訴它要這樣做,它就會完全放棄尋呼機。這是出乎意料的。但我欺騙了它並使用 sed 的w
rite 函數將其寫入 >&2 並重定向它,所以它並不明智。
但要注意的是,@terdon 的可能是更好的方法。雖然您可以更輕鬆地自訂此操作,因為您獲得了sed
每個文件,並且格式設定要好一些,因為它不會嘗試適應終端寬度,但顯然man
不會將這些 \backslashes 寫入|pipe
.