Drucken Sie Manpages mit fester Breite

11

Mit dem Beispielbefehl

man apropos > outputfile

Es wird eine Textdatei generiert, die die formatierte manSeite von enthält apropos(mit einigen kleinen Unterschieden in Bezug auf man aproposdirekt auf dem Bildschirm gedruckte, z. B. fett gedruckte Zeichen).

Ich möchte jedoch die maximale Zeilenbreite der generierten Ausgabedatei manuell festlegen, damit alle Absätze auf diese Breite ausgerichtet werden.

manSeiten werden erstellt durch groff: Ich habe beispielsweise versucht, .ll 50einen Absatz der ursprünglichen .gz manQuelltextdatei vorzulegen, aber es ist trivial, wenn ich an mehreren manSeiten arbeiten muss. Außerdem werden nicht alle Zeichen erkannt:

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

Ich frage mich also, ob es eine einfachere Methode gibt. Wie ändere ich die maximale Linienbreite während der Erstellung eines outputfile? Gibt es einen bestimmten Befehl?


Bearbeiten :

(Alle folgenden Überlegungen beziehen sich auf Ubuntu 18.04: Ich kann sie in früheren Versionen nicht mehr testen, einschließlich 14.04 der obigen Frage.)

Bei einer einzeiligen temporären Lösung MANWIDTHgibt es keinen Unterschied , wenn sie noch nicht mit einem benutzerdefinierten Wert exportiert wurde

$ MANWIDTH=60 man apropos > outputfile

und

$ COLUMNS=60 man apropos > outputfile

Die erste Verwendung MANWIDTHist jedoch im Prinzip besser.


Bearbeiten 2 (nicht eng mit der Frage verbunden):

Um stattdessen eine permanente Breiteneinstellung vorzunehmen, die auf jeden Manpage-Druck angewendet werden soll, muss der gewünschte Wert der Variablen exportiert werden. Mit:

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

man aproposwird unabhängig von der Größe des Terminalfensters mit derselben Breite gedruckt. Stattdessen,

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

liefert nur dann das gleiche Ergebnis wie zuvor, wenn die Größe des Terminalfensters zwischen exportund nicht geändert wird man <page> > outputfile.

BowPark
quelle
Ich kann Ihre input codeFehler nicht reproduzieren , 195 168 könnte in UTF-8 sein. Ist die Manpage auf Englisch? Was ist Ihre Mann-Implementierung? Was ist dein Gebietsschema?
Stéphane Chazelas
Das System ist Ubuntu 14.04 (Version von man manist 2.6.7.1). Die Manpage ist in Italienisch und es ist UTF-8. Was meinst du mit Gebietsschema?
BowPark
Was ist die Ausgabe von locale? und locale charmap?
Stéphane Chazelas
localeAusgabe: LANG=it_IT.UTF-8 LANGUAGE= LC_CTYPE="it_IT.UTF-8" LC_NUMERIC="it_IT.UTF-8" locale charmapAusgabe:UTF-8
BowPark
1
Ja , das Terminal nicht funktionsfähig ist von lessda TERMnicht festgelegt ist. Ich meinte env -i LANG=it_IT.UTF-8 man apropos > output(oder | head).
Stéphane Chazelas

Antworten:

18

Verwenden Sie die MANWIDTHUmgebungsvariable:

MANWIDTH=60 man apropos > apropos.txt

Die Manpage für man 2.7.4 sagt:

Wenn $ MANWIDTH festgelegt ist, wird sein Wert als Zeilenlänge verwendet, für die Handbuchseiten formatiert werden sollen. Wenn es nicht festgelegt ist, werden Handbuchseiten mit einer Zeilenlänge formatiert, die dem aktuellen Terminal entspricht (unter Verwendung des Werts $ COLUMNS, eines ioctl (2), falls verfügbar, oder unter Verwendung von 80 Zeichen, falls keines verfügbar ist).

Das heißt, es überschreibt sowohl COLUMNSals auch den ioctlWert. Ich ziehe es vor, mich nicht auf Änderungen zu verlassen COLUMNS(obwohl dies hier funktioniert), da der Wert jedes Mal dynamisch aktualisiert wird, wenn sich die Fenstergröße ändert.

Wenn Sie MANWIDTHanstelle von verwenden, COLUMNSkönnen Sie die Änderung auch dauerhaft machen, indem Sie eine Zeile hinzufügen, z. B. export MANWIDTH=60zu Ihrer Shell-Startdatei.

Marcel M.
quelle
Exzellente Arbeit. Ich wollte auch COLUMNS nicht ändern, und MANWIDTH arbeitet in RHEL5. Prost.
Felipe Alvarez
1
Ein Hinweis für die Leser: Möglicherweise müssen Sie verwenden, export MANWIDTH=60wenn Sie dies in Ihrem einstellen ~/.bashrc. Siehe stackoverflow.com/a/30173376/82216 . manZiehen Sie auch in Betracht, eine Funktion einzuschließen, um MANWIDTH abhängig von Ihrer Terminalbreite festzulegen, wie hier im Arch-Wiki vorgeschlagen.
Sampablokuper
@Marcel M Vielen Dank für Ihre sehr genaue Antwort. Können Sie bitte das Update in der Frage lesen und Ihre Antwort bearbeiten, um den grundlegenden Vorschlag zu enthalten export MANWIDTH=60?
BowPark
@BowPark Ich habe die Antwort ohne geschrieben, exportweil Sie nach einer temporären Lösung gefragt haben: "Wie ändere ich die maximale Zeilenbreite während der Erstellung einer Ausgabedatei? " (Hervorhebung meiner). Möglicherweise möchten Sie Ihre Bearbeitung sogar zurücksetzen, da sie der Frage nicht hinzugefügt wird. (Ein Kommentar ist angemessener.)
Marcel M
@MarcelM Eigentlich hast du recht. Ich habe die Frage entsprechend bearbeitet. Ich habe eine zweite Bearbeitung mit den exportAussagen geschrieben, weil sie in einem Kommentar fast unlesbar wäre (es ist nicht möglich, Zeilenumbrüche zu erstellen).
BowPark
10

Versuchen Sie, die COLUMNSUmgebungsvariable festzulegen. Funktioniert für mich mit manab mandb2.7.0.2 unter Debian mit 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 ...

Mit der Version unter Ubuntu 14.04 muss ich es schreiben:

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

Dort, man scheint die COLUMNSUmgebungsvariable zu ignorieren , wenn stdin ein Terminal ist (es fragt dann das Terminalgerät nach der Terminalbreite ab).

Sie können auch versuchen:

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

Welches mit zsh Ihnen verkürzen kann auf:

STTY='cols 60' man apropos | head

Sie können dies durch Aufrufen tun groff von Hand :

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

Sie können Zeichen mit Eingabecodefehlern nicht finden, weil Sie die Dateien -Tasciianstelle von verwendet -Tutf8und nicht verwendet haben -k, um sie vorzuverarbeiten preconv.

Stéphane Chazelas
quelle
Ich habe den gleichen Befehl versucht: COLUMNS=60 man apropos | headaber leider ist die Ausgabebreite die gesamte Bildschirmbreite. Kann ich die Variable an COLUMNSanderer Stelle oder auf andere Weise festlegen ?
BowPark
2
Versuchen Sie es COLUMNS=60 < /dev/null man apropos | head. Sieht aus wie unter Ubuntu 14.04, es vertraut nicht, COLUMNSob stdin ein Terminal ist (und erhält die Breite vom Endgerät).
Stéphane Chazelas
Vielleicht ist es so, wie du angenommen hast. Und jetzt funktioniert es, danke!
BowPark
4

Sie können den fmtBefehl verwenden, der meines Wissens in jeder Linux-Distribution vorhanden ist.

man apropos | fmt -w 70 

schließt Zeilen mit 70 Zeichen ein.

dr01
quelle
1
Ja, ich habe es, danke, es funktioniert und es ist ziemlich nützlich, aber ich brauche einen begründeten Text und es wird stattdessen einfach Zeilen umbrochen.
BowPark
Entschuldigung, ich muss diesen Teil verpasst haben.
Dr01
2

Sie können verwenden fold

man cp | fold -w 20

wird nach jeweils 20 Zeichen (!) gefaltet. Beachten Sie, dass dadurch Wörter in zwei Teile geteilt werden, da die einzige Option "Alle 20 Zeichen falten" ist.

Um dies zu gewährleisten, können Sie sedFolgendes verwenden (mit dynamischer Linienlänge)

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

fügt nach 20 zufälligen Zeichen eine neue Zeile hinzu, gefolgt von einem Leerzeichen (dh einem neuen Wort). Zeilen können also länger als 20 Zeichen sein (Übereinstimmung ist 20 Zeichen, dann ein Leerzeichen, sodass ein Wort mit 26 Zeichen zu einer Zeile mit 26 Zeichen führen würde).

Zum Weglassen des letzten Leerzeichens im sedBefehl:

sed 's/\(.\{20\}\) /\1\n/g'
Fiximan
quelle
1
Vielen Dank, ich habe Ihre Beispiele ausprobiert und sie funktionieren, aber - wie in einem Kommentar zu dr01 geschrieben - brauche ich einen begründeten Text.
BowPark