Imprimir páginas de manual com largura fixa

11

Com o comando de exemplo

man apropos > outputfile

é gerado um arquivo de texto que contém a manpágina formatada de apropos(com algumas pequenas diferenças em relação a man aproposimpressos diretamente na tela, como caracteres em negrito).

Mas eu gostaria de definir manualmente a largura máxima da linha do arquivo de saída gerado, para que todos os parágrafos sejam justificados para essa largura.

manas páginas são criadas através de groff: por exemplo, tentei colocar .ll 50antes de um parágrafo do .gz manarquivo de texto original , mas é trivial se eu precisar trabalhar em várias manpáginas. Além disso, nem todos os personagens são reconhecidos:

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

Então, eu me pergunto se existe um método mais direto. Como modificar a largura máxima da linha, durante a criação de um outputfile? Existe algum comando específico?


Editar :

(Todas as considerações a seguir são sobre o Ubuntu 18.04: Não posso mais testá-las nas versões anteriores, incluindo a 14.04 da pergunta acima.)

No que diz respeito a uma solução temporária de uma linha, se MANWIDTHainda não tiver sido exportada com um valor personalizado, não há diferença entre

$ MANWIDTH=60 man apropos > outputfile

e

$ COLUMNS=60 man apropos > outputfile

O primeiro, usando MANWIDTH, é no entanto melhor em princípio.


Editar 2 (não estritamente relacionado à pergunta):

Para criar uma configuração de largura permanente a ser aplicada a qualquer impressão de página de manual, é necessário exportar o valor desejado da variável. Com:

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

man aproposserá impresso com a mesma largura, independentemente de qualquer redimensionamento da janela do terminal. Em vez de,

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

fornecerá o mesmo resultado de antes apenas se a janela do terminal não for redimensionada entre exporte man <page> > outputfile.

BowPark
fonte
Não consigo reproduzir seus input codeerros 195 168 podem estar em UTF-8. A página do manual está em inglês? Qual é a sua implementação man? Qual é a sua localidade?
Stéphane Chazelas
o sistema é o Ubuntu 14.04 (a versão man mané 2.6.7.1). A página do manual está em italiano e é UTF-8. O que você quer dizer com localidade?
BowPark
Qual é o resultado de locale? e locale charmap?
Stéphane Chazelas
localesaída: LANG=it_IT.UTF-8 LANGUAGE= LC_CTYPE="it_IT.UTF-8" LC_NUMERIC="it_IT.UTF-8" locale charmapsaída:UTF-8
BowPark 11/08
1
Sim, o terminal não funciona é lessporque TERMnão está definido. Eu quis dizer env -i LANG=it_IT.UTF-8 man apropos > output(ou | head).
Stéphane Chazelas 12/08/2015

Respostas:

18

Use a MANWIDTHvariável de ambiente:

MANWIDTH=60 man apropos > apropos.txt

A página de manual do man 2.7.4 diz:

Se $ MANWIDTH for definido, seu valor será usado como o comprimento da linha para o qual as páginas de manual devem ser formatadas. Se não estiver definido, as páginas de manual serão formatadas com um comprimento de linha apropriado ao terminal atual (usando o valor de $ COLUMNS, um ioctl (2) se disponível, ou retornando a 80 caracteres, se nenhum estiver disponível).

Ou seja, substitui ambos COLUMNSe o ioctlvalor. Prefiro não confiar na modificação COLUMNS(embora funcione aqui), pois seu valor é atualizado dinamicamente sempre que o tamanho da janela é alterado.

Usar em MANWIDTHvez de COLUMNStambém permite que você faça a alteração permanente, adicionando uma linha como export MANWIDTH=60no seu arquivo de inicialização do shell.

Marcel M
fonte
Excelente trabalho. Também não queria alterar COLUMNS, e MANWIDTH é uma delícia no RHEL5. Felicidades.
Felipe Alvarez
1
Uma observação para os leitores: você pode precisar usar export MANWIDTH=60se definir isso no seu ~/.bashrc. Consulte stackoverflow.com/a/30173376/82216 . Além disso, considere managrupar uma função para definir MANWIDTH dependendo da largura do seu terminal, conforme sugerido aqui no wiki do Arch.
sampablokuper
@ Marcel M Obrigado por sua resposta muito precisa. Você pode ler a atualização na pergunta e editar sua resposta para incluir a sugestão fundamental sobre export MANWIDTH=60?
BowPark
O @BowPark escrevi a resposta sem exportporque você perguntou sobre uma solução temporária: "Como modificar a largura máxima da linha, durante a criação de um arquivo de saída? " (Ênfase minha). Você pode até reverter sua edição, pois ela não contribui para a pergunta. (Um comentário é mais apropriado.)
Marcel M
@MarcelM Na verdade, você está certo. Eu editei a pergunta de acordo. Escrevi uma segunda edição com as exportdeclarações, porque em um comentário seria quase ilegível (não sendo possível criar novas linhas).
BowPark
10

Tente definir a COLUMNSvariável de ambiente. Obras para me com mana partir de mandb2.7.0.2 no Debian com groff1.22.3.

$ 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 ...

Com a versão no Ubuntu 14.04, preciso escrever:

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

Lá, manparece desconsiderar a COLUMNSvariável de ambiente se stdin for um terminal (ele consulta o dispositivo do terminal quanto à largura do terminal).

Você também pode tentar:

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

Com zshvocê, você pode reduzir para:

STTY='cols 60' man apropos | head

Você pode fazer isso invocando groffmanualmente como:

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

Seu personagem não pode se encontrar com código de entrada erros foram porque você usou -Tasciiem vez de -Tutf8e não usar -ka pré-processar os arquivos com preconv.

Stéphane Chazelas
fonte
Eu tentei o mesmo comando COLUMNS=60 man apropos | head:, mas infelizmente a largura de saída é toda a largura da tela. Posso definir a variável COLUMNSem outro lugar ou de outra maneira?
BowPark
2
Tente COLUMNS=60 < /dev/null man apropos | head. Parece que no Ubuntu 14.04, não confia COLUMNSse stdin é um terminal (e obtém a largura do dispositivo do terminal).
Stéphane Chazelas
Talvez seja como você deveria. E agora funciona, obrigado!
BowPark
4

Você pode usar o fmtcomando, que, tanto quanto eu sei, está presente em qualquer distribuição Linux.

man apropos | fmt -w 70 

irá agrupar linhas com 70 caracteres.

dr01
fonte
1
sim, obrigado, funciona e é bastante útil, mas preciso de um texto justificado e, em vez disso, basta agrupar as linhas.
BowPark
Desculpe, eu devo ter perdido essa parte.
Dr01
2

Você pode usar fold

man cp | fold -w 20

dobrará após cada 20 caracteres (!). Observe que isso cortará as palavras em dois, pois a única opção é "dobrar a cada 20 caracteres"

cuidando disso, você pode usar sedo seguinte (com comprimento de linha dinâmico)

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

adicionará uma nova linha após 20 caracteres aleatórios seguidos por um espaço (ou seja, nova palavra). Portanto, as linhas podem ter mais de 20 caracteres (a correspondência é de 20 caracteres e um espaço para que uma palavra de 26 caracteres resulte em uma linha de 26 caracteres)

Para omitir o último espaço no sedcomando:

sed 's/\(.\{20\}\) /\1\n/g'
Fiximan
fonte
1
Obrigado, tentei seus exemplos e eles funcionam, mas - conforme escrito em um comentário para dr01 - preciso de um texto justificado.
BowPark