的确,某些shell内置程序在完整的手册中可能很少显示-尤其是对于那些bash
特定的内置程序,您只可能在GNU系统上使用它们(通常,GNU人士不要相信man
和偏好自己的info
页面) -绝大多数POSIX实用程序(shell内置或其他)在POSIX程序员指南中都有很好的表示。
这是我底部的摘录man sh
(可能长20页左右...)
所有这些都在那里,和其他人没有提到这样的set
,read
,break
...好,我不需要给它们命名所有。但是请注意(1P)
右下角的-它表示POSIX 1类手册系列-这些是man
我正在谈论的页面。
可能只是您需要安装软件包?对于Debian系统,这看起来很有希望。虽然help
很有用,但是如果可以找到它,则一定要获得该POSIX Programmer's Guide
系列文章。这可能非常有帮助。它的组成页面非常详细。
除此之外,shell内置文件几乎总是在特定的shell手册的特定部分中列出。zsh
,例如,有一个完整的单独man
页面- (我认为总共有8或9个左右的zsh
页面-包括zshall
很大的页面。)
您grep
man
当然可以:
man bash 2>/dev/null |
grep '^[[:blank:]]*read [^`]*[-[]' -A14
read [-ers] [-a aname] [-d delim] [-i text] [-n
nchars] [-N nchars] [-p prompt] [-t timeout] [-u
fd] [name ...]
One line is read from the standard input, or
from the file descriptor fd supplied as an
argument to the -u option, and the first
word is assigned to the first name, the sec‐
ond word to the second name, and so on, with
leftover words and their intervening separa‐
tors assigned to the last name. If there
are fewer words read from the input stream
than names, the remaining names are assigned
empty values. The characters in IFS are
used to split the line into words using the
same rules the shell uses for expansion
...这与我在搜索Shell man
页面时所做的非常接近。但是在大多数情况下,这help
是相当不错的bash
。
实际上,我最近一直在sed
处理脚本来处理这种事情。这就是我抓取上图中的部分的方式。它的长度比我喜欢的还要长,但是它正在改进-可以非常方便。在当前的迭代中,它将基于命令行中给定的[a]模式,非常可靠地提取与上下文相关的文本节,该文本与节或小节标题匹配。它为输出着色并打印到标准输出。
它通过评估缩进级别来工作。非空白输入行通常被忽略,但是当遇到空白行时,它开始引起注意。它从那里开始收集行,直到确认当前序列肯定比第一行缩进为止,然后再出现另一条空行,否则它将丢弃线程并等待下一个空行。如果测试成功,它将尝试将引线与其命令行参数匹配。
这意味着匹配模式将匹配:
heading
match ...
...
...
text...
..和..
match
text
..但不是..
heading
match
match
notmatch
..要么..
text
match
match
text
more text
如果可以进行匹配,它将开始打印。它将从打印的所有行中去除匹配行的前导空白-因此,无论缩进级别是多少,只要发现它在该行上的行都像打印在顶部一样,就可以缩进。它会继续打印,直到遇到与匹配行相等或小于缩进级别的另一行为止-因此,整个节仅以标题匹配项(包括任何/所有小节及其可能包含的段落)进行抓取。
因此,基本上,如果您要求它匹配某个模式,它只会针对某种主题标题进行匹配,并且会对其匹配的标题部分中找到的所有文本进行着色和打印。除了第一行的缩进以外,什么也不会保存,因此它可以非常快地处理\n
几乎任何大小的单行分隔输入。
我花了一段时间才弄清楚如何递归到以下子标题:
Section Heading
Subsection Heading
但我最终对其进行了整理。
不过,为了简单起见,我确实必须对整个过程进行重新设计。在我有几个小循环以适应它们的上下文的方式以略有不同的方式执行大多数相同的事情之前,通过改变其递归方式,我设法对大多数代码进行了重复数据删除。现在有两个循环-一个打印和一个检查缩进。两者都依赖于同一测试-打印循环在测试通过时开始,缩进循环在测试失败或从空白行开始时接管。
整个过程非常快,因为在大多数情况下,它只会/./d
清除任何非空白行并移至下一行-即使zshall
是立即填充屏幕也会导致结果。这没有改变。
无论如何,到目前为止,它还是非常有用的。例如,read
上面的事情可以这样完成:
mansed bash read
...并获得整个区块。它可以采用任何模式或其他方式,也可以采用多个参数,尽管第一个始终是man
它应该在其中搜索的页面。这是我做完之后的一些输出图片:
mansed bash read printf
...两个块都全部返回。我经常像这样使用它:
mansed ksh '[Cc]ommand.*'
...这是非常有用的。另外,获取SYNOPS[ES]
变得非常方便:
在这里,如果您想旋转一下-如果您不这样做,我不会怪您。
mansed() {
MAN_KEEP_FORMATTING=1 man "$1" 2>/dev/null | ( shift
b='[:blank:]' s='[:space:]' bs=$(printf \\b) esc=$(printf '\033\[') n='\
' match=$(printf "\([${b}]*%s[${b}].*\)*" "$@")
sed -n "1p
/\n/!{ /./{ \$p;d
};x; /.*\n/!g;s///;x
:indent
/.*\n\n/{s///;x
};n;\$p;
/^\([^${s}].*\)*$/{s/./ &/;h; b indent
};x; s/.*\n[^-[]*\n.*//; /./!x;t
s/[${s}]*$//; s/\n[${b}]\{2,\}/${n} /;G;h
};
#test
/^\([${b}]*\)\([^${b}].*\n\)\1\([${b}]\)/!b indent
s//\1\2.\3/
:print
/^[${s}]*\n\./{ s///;s/\n\./${n}/
/${bs}/{s/\n/ & /g;
s/\(\(.\)${bs}\2\)\{1,\}/${esc}38;5;35m&${esc}0m/g
s/\(_${bs}[^_]\)\{1,\}/${esc}38;5;75m&${esc}0m/g
s/.${bs}//g;s/ \n /${n}/g
s/\(\(${esc}\)0m\2[^m]*m[_ ]\{,2\}\)\{2\}/_/g
};p;g;N;/\n$/!D
s//./; t print
};
#match
s/\n.*/ /; s/.${bs}//g
s/^\(${match}\).*/${n}\1/
/../{ s/^\([${s}]*\)\(.*\)/\1${n}/
x; s//${n}\1${n}. \2/; P
};D
");}
简而言之,工作流程是:
\n
从输出中删除所有非空白且不包含尾行字符的行。
\n
在输入模式空间中永远不会出现行字符。它们只能作为编辑的结果。
:print
和:indent
都是相互依赖的闭环,并且是获得\n
直线的唯一方法。
:print
如果一行上的前导字符是一系列空格后跟一个\n
ewline字符,则开始循环循环。
:indent
的循环从空白行开始-或在:print
失败的循环行上开始#test
-但:indent
会\n
从其输出中删除所有开头的空白+ ewline序列。
- 一旦
:print
开始,它将继续拉入输入行,将前导空白删除到其循环中第一行所找到的数量,将过分删除和欠删除退格转义转换为彩色终端转义,并打印结果直到#test
失败。
- 在
:indent
开始之前,它首先检查h
旧空间是否有任何可能的缩进延续(例如Subsection),然后只要#test
失败就继续输入,并且第一个之后的任何行都继续匹配[-
。当第一行之后的行与该模式不匹配时,将其删除-随后,所有后续行也将删除,直到下一个空白行。
#match
并#test
桥接两个闭环。
#test
当空白行的前导序列比\n
行序列中的最后一条ewline短时,将通过。
#match
将\n
开始:print
循环所需的前导行添加到任何:indent
与任何命令行arg匹配的输出序列中。那些不会变成空的序列-产生的空行被传回:indent
。