以固定宽度打印手册页

以固定宽度打印手册页

使用示例命令

man apropos > outputfile

生成一个文本文件,其中包含格式化的man页面apropos(与man apropos直接打印在屏幕上有一些细微的差别,例如粗体字符)。

但我想手动设置生成的输出文件的最大行宽,以便所有段落都对齐到该宽度。

man页面是通过以下方式创建的groff:例如,我尝试将.ll 50原始源文本文件的一段放在前面.gz man,但如果我需要在多个页面上工作,则这是微不足道的man。此外,并非所有字符都被识别:

apropos.1:45: warning: can't find character with input code 195
apropos.1:45: warning: can't find character with input code 168
apropos.1:47: warning: can't find character with input code 178
apropos.1:131: warning: can't find character with input code 169

所以我想知道是否存在更直接的方法。如何在创建过程中修改最大线宽outputfile?有具体的命令吗?


编辑:

(以下所有注意事项都是关于Ubuntu 18.04:我无法再在以前的版本中测试它们,包括上述问题的14.04。)

对于单行临时解决方案,如果MANWIDTH尚未使用自定义值导出,则两者之间没有区别

$ MANWIDTH=60 man apropos > outputfile

$ COLUMNS=60 man apropos > outputfile

然而,第一个使用 ,MANWIDTH原则上更好。


编辑2(与问题不严格相关):

要改为将永久宽度设置应用于任何手册页打印,有必要出口变量的期望值。和:

$ export MANWIDTH=60
# zero or more additional lines
$ man apropos > outputfile

man apropos无论终端窗口大小如何调整,都将以相同的宽度打印。反而,

$ export COLUMNS=60
# zero or more additional lines
$ man apropos > outputfile

仅当终端窗口未在export和之间调整大小时,才会提供与之前相同的结果man <page> > outputfile

答案1

使用MANWIDTH环境变量:

MANWIDTH=60 man apropos > apropos.txt

man 2.7.4 的联机帮助页显示:

如果设置了 $MANWIDTH,则其值将用作手册页应格式化的行长度。如果未设置,则手册页将采用适合当前终端的行长度进行格式化(使用 $COLUMNS 的值、ioctl(2)(如果可用),或者回退到 80 个字符(如果两者都不可用)。

也就是说,它会覆盖COLUMNSioctl值。我宁愿不依赖于修改COLUMNS(尽管它在这里确实有效),因为每次窗口大小变化时它的值都会动态更新。

使用MANWIDTH代替还允许您通过在 shell 启动文件中COLUMNS添加一行来使更改永久化。export MANWIDTH=60

答案2

尝试设置COLUMNS环境变量。我可以在 Debian 1.22.3 上使用 2.7.0.2man版本。mandbgroff

$ COLUMNS=60 man apropos | head
APROPOS(1)          Manual pager utils          APROPOS(1)



NAME
       apropos - search the manual page names and descrip‐
       tions

SYNOPSIS
       apropos [-dalv?V] [-e|-w|-r]  [-s  list]  [-m  sys‐

$ COLUMNS=70 man apropos | head
APROPOS(1)               Manual pager utils               APROPOS(1)



NAME
       apropos - search the manual page names and descriptions

SYNOPSIS
       apropos  [-dalv?V] [-e|-w|-r] [-s list] [-m system[,...]] [-M
       path] [-L locale] [-C file] keyword ...

对于Ubuntu 14.04上的版本,我需要这样写:

COLUMNS=60 < /dev/null man apropos | head

在那里,如果 stdin 是终端,man似乎会忽略环境变量(然后它会查询终端设备的终端宽度)。COLUMNS

您还可以尝试:

s=$(stty -g); stty cols 60; man apropos | head; stty "$s"

zsh可以将其缩短为:

STTY='cols 60' man apropos | head

您可以通过groff手动调用来完成此操作:

gzip -dcf "$(man -w apropos)" |
  groff -ekpstR -mtty-char -mandoc -Tutf8 -rLL=60n |
  col -bpx

其中groff选项是:


# Native groff Options

-e     eqn      (equations)
-k     preconv  (encoding for groff)
-p     pic      (pictures)
-s     soelim   (.so requests - source file)
-t     tbl      (format tables)
-R     refer    (bibliography)

# Transparent Options

-mtty-char
      Overrides  the  definition of standard  troff characters  and
      some groff characters for TTY devices. The optical appearance
      is  intentionally inferior  compared to  that  of normal  TTY 
      formatting to allow processing with critical  equipment.

-mandoc
      Use this file  in case you don't know  whether the man macros
      or the mdoc package should be used.    Multiple man pages (in 
      either format) can be handled.

-R     utf8     (output-encoding)


-r     LL=60n   (Number of LL registers)

你的无法找到带输入代码的字符错误是因为您使用-Tascii-Tutf8不是使用-k来预处理文件preconv

答案3

您可以使用该fmt命令,据我所知,任何 Linux 发行版中都存在该命令。

man apropos | fmt -w 70 

将在 70 个字符处换行。

答案4

您可以使用fold

man cp | fold -w 20

每 20 个字符后就会折叠(!)。请注意,这会将单词切成两半,因为唯一的选项是“每 20 个字符折叠一次”

考虑到这一点,您可以sed按如下方式使用(具有动态行长度)

man cp | sed 's/.\{20\} /&\n/g'

将在 20 个随机字符后添加一个换行符,后跟一个空格(即新单词)。因此,行的长度可能超过 20 个字符(匹配是 20 个字符,然后是一个空格,因此 26 个字符的单词将生成 26 个字符的行)

省略sed命令中的最后一个空格:

sed 's/\(.\{20\}\) /\1\n/g'

相关内容