Drukuj strony podręcznika o stałej szerokości

11

Za pomocą polecenia przykładowego

man apropos > outputfile

generowany jest plik tekstowy, który zawiera sformatowaną manstronę apropos(z pewnymi niewielkimi różnicami w odniesieniu do man aproposbezpośrednio drukowanych na ekranie, takich jak pogrubione znaki).

Chciałbym jednak ręcznie ustawić maksymalną szerokość linii generowanego pliku wyjściowego, aby wszystkie akapity były wyrównane do tej szerokości.

manstrony są tworzone przez groff: na przykład próbowałem umieścić .ll 50przed akapitem oryginalnego .gz manźródłowego pliku tekstowego, ale jest to trywialne, jeśli muszę pracować na kilku manstronach. Ponadto nie wszystkie znaki są rozpoznawane:

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

Zastanawiam się więc, czy istnieje bardziej prosta metoda. Jak zmodyfikować maksymalną szerokość linii podczas tworzenia outputfile? Czy jest jakieś konkretne polecenie?


Edytuj :

(Wszystkie poniższe uwagi dotyczą Ubuntu 18.04: Nie mogę ich więcej testować w poprzednich wersjach, w tym 14.04 powyższego pytania.)

Jeśli chodzi o tymczasowe jednowierszowe rozwiązanie, jeśli MANWIDTHnie zostało jeszcze wyeksportowane z wartością niestandardową, nie ma między nimi żadnej różnicy

$ MANWIDTH=60 man apropos > outputfile

i

$ COLUMNS=60 man apropos > outputfile

Pierwszy z nich MANWIDTHjest jednak zasadniczo lepszy.


Edycja 2 (nie ściśle związana z pytaniem):

Aby zamiast tego ustawić stałe ustawienie szerokości, które ma być zastosowane do każdego wydruku strony, konieczne jest wyeksportowanie pożądanej wartości zmiennej. Z:

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

man aproposzostanie wydrukowany z tą samą szerokością, niezależnie od zmiany rozmiaru okna terminala. Zamiast,

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

zapewni taki sam wynik jak poprzednio tylko wtedy, gdy okno terminala nie zostanie przeskalowane pomiędzy exporti man <page> > outputfile.

BowPark
źródło
Nie mogę odtworzyć twoich input codebłędów 195 168 może być w UTF-8. Czy strona podręcznika jest w języku angielskim? Jaka jest implementacja twojego człowieka? Jakie są twoje ustawienia regionalne?
Stéphane Chazelas,
system to Ubuntu 14.04 (wersja od man man2.6.7.1). Strona podręcznika jest w języku włoskim i jest to UTF-8. Co rozumiesz przez ustawienia regionalne?
BowPark,
Jaka jest wydajność locale? i locale charmap?
Stéphane Chazelas,
localewyjście: LANG=it_IT.UTF-8 LANGUAGE= LC_CTYPE="it_IT.UTF-8" LC_NUMERIC="it_IT.UTF-8" locale charmapwyjście:UTF-8
BowPark,
1
Tak, to terminal nie funkcjonalny jest z lessponieważ TERMnie jest ustawiony. Miałem na myśli env -i LANG=it_IT.UTF-8 man apropos > output(lub | head).
Stéphane Chazelas,

Odpowiedzi:

19

Użyj MANWIDTHzmiennej środowiskowej:

MANWIDTH=60 man apropos > apropos.txt

Strona man dla man 2.7.4 mówi:

Jeśli ustawiono $ MANWIDTH, jego wartość jest używana jako długość linii, dla której należy sformatować strony podręcznika. Jeśli nie jest ustawiony, strony podręcznika zostaną sformatowane z długością linii odpowiednią dla bieżącego terminala (przy użyciu wartości $ COLUMNS, ioctl (2), jeśli jest dostępny, lub powrotu do 80 znaków, jeśli żaden nie jest dostępny).

Oznacza to, że zastępuje zarówno wartość, jak COLUMNSi ioctlwartość. Wolę nie polegać na modyfikowaniu COLUMNS(chociaż tutaj działa), ponieważ jego wartość jest aktualizowana dynamicznie za każdym razem, gdy zmienia się rozmiar okna.

Użycie MANWIDTHzamiast COLUMNSpozwala również na trwałe wprowadzenie zmiany poprzez dodanie wiersza, na przykład export MANWIDTH=60do pliku startowego powłoki.

Marcel M.
źródło
Świetna robota. Nie chciałem też zmieniać COLUMNS, a MANWIDTH działa w RHEL5. Twoje zdrowie.
Felipe Alvarez
1
Uwaga dla czytelników: może być konieczne użycie, export MANWIDTH=60jeśli ustawisz to w swoim ~/.bashrc. Zobacz stackoverflow.com/a/30173376/82216 . Rozważ także zawijanie manfunkcji, aby ustawić MANWIDTH w zależności od szerokości terminala, jak sugerowano tutaj na wiki Arch.
sampablokuper,
@Marcel M Dziękujemy za bardzo dokładną odpowiedź. Czy możesz przeczytać aktualizację w pytaniu i edytować swoją odpowiedź, aby uwzględnić podstawową sugestię na temat export MANWIDTH=60?
BowPark
@BowPark Napisałem odpowiedź bez, exportponieważ zapytałeś o tymczasowe rozwiązanie: „Jak zmodyfikować maksymalną szerokość linii podczas tworzenia pliku wyjściowego? ” ( Moje podkreślenie). Możesz nawet cofnąć swoją edycję, ponieważ nie dodaje się ona do pytania. (Komentarz jest bardziej odpowiedni.)
Marcel M
@MarcelM Właściwie masz rację. Zredagowałem to pytanie odpowiednio. Napisałem drugą edycję z exportinstrukcjami, ponieważ w komentarzu byłoby to prawie nieczytelne (nie byłoby możliwe utworzenie nowego wiersza).
BowPark
10

Spróbuj ustawić COLUMNSzmienną środowiskową. Pracuje dla mnie manz mandb2.7.0.2 na Debianie z 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 ...

W wersji na Ubuntu 14.04 muszę to napisać:

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

Tam manwydaje się lekceważyćCOLUMNS zmienną środowiskową, jeśli stdin jest terminalem (następnie pyta urządzenie końcowe o szerokość terminala).

Możesz także spróbować:

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

Które z zshTobą możesz skrócić do:

STTY='cols 60' man apropos | head

Możesz to zrobić, wywołując groffręcznie jako:

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

Twój nie może znaleźć postać z kodów wejściowych błędów, ponieważ były używane -Tasciizamiast -Tutf8, a nie korzystać -kz wcześniej przetwarzać pliki preconv.

Stéphane Chazelas
źródło
Próbowałem tego samego polecenia: COLUMNS=60 man apropos | headale niestety szerokość wyjściowa to cała szerokość ekranu. Czy mogę ustawić zmienną COLUMNSgdzie indziej lub w inny sposób?
BowPark,
2
Spróbować COLUMNS=60 < /dev/null man apropos | head. Wygląda jak w Ubuntu 14.04, nie ufa, COLUMNSjeśli stdin jest terminalem (i pobiera szerokość z urządzenia końcowego).
Stéphane Chazelas,
Może to tak, jak przypuszczałeś. A teraz działa, dziękuję!
BowPark,
4

Możesz użyć fmtpolecenia, które, o ile mi wiadomo, jest obecne w dowolnej dystrybucji Linuksa.

man apropos | fmt -w 70 

zawinie linie o długości 70 znaków.

dr_
źródło
1
tak, mam, dziękuję, działa i jest całkiem użyteczny, ale potrzebuję uzasadnionego tekstu i po prostu zawijam wiersze.
BowPark,
Przepraszam, musiałem przegapić tę część.
dr_
2

Możesz użyć fold

man cp | fold -w 20

będzie pasować po każdych 20 znakach (!). Pamiętaj, że spowoduje to przecięcie słów na dwie części, ponieważ jedyną opcją jest „pasuj co 20 znaków”

dbając o to, możesz użyć sedw następujący sposób (z dynamiczną długością linii)

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

doda nowy wiersz po 20 losowych znakach, po których nastąpi spacja (tj. nowe słowo). Tak więc linie mogą być dłuższe niż 20 znaków (dopasowanie to 20 znaków, a następnie spacja, więc słowo składające się z 26 znaków może dać wiersz składający się z 26 znaków)

Aby pominąć ostatnią spację w sedpoleceniu:

sed 's/\(.\{20\}\) /\1\n/g'
Fiximan
źródło
1
Dziękuję, wypróbowałem twoje przykłady i działają, ale - jak napisano w komentarzu do dr01 - potrzebuję uzasadnionego tekstu.
BowPark,