Распечатайте справочные страницы с фиксированной шириной

11

С помощью команды примера

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 (не строго связано с вопросом):

Чтобы вместо этого установить постоянную ширину для любой печати man-страницы, необходимо экспортировать требуемое значение переменной. С:

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

BowPark
источник
Я не могу воспроизвести ваши input codeошибки, 195 168 может быть, в UTF-8. Справочная страница на английском? Какая у тебя мужская реализация? Какой у тебя язык?
Стефан Шазелас
система Ubuntu 14.04 (версия от man man2.6.7.1). Страница руководства на итальянском языке, и это UTF-8. Что вы подразумеваете под языком?
BowPark
Какой выход locale? а locale charmap?
Стефан Шазелас
localeвыходные данные: LANG=it_IT.UTF-8 LANGUAGE= LC_CTYPE="it_IT.UTF-8" LC_NUMERIC="it_IT.UTF-8" locale charmapвыходные данные:UTF-8
BowPark
1
Да терминал не работает от , lessпотому что TERMне установлен. Я имел ввиду env -i LANG=it_IT.UTF-8 man apropos > output(или | head).
Стефан Шазелас

Ответы:

18

Используйте MANWIDTHпеременную окружения:

MANWIDTH=60 man apropos > apropos.txt

Man-страница для человека 2.7.4 гласит:

Если установлено значение $ MANWIDTH, его значение используется в качестве длины строки, для которой должны быть отформатированы страницы руководства. Если он не установлен, страницы справочника будут отформатированы с длиной строки, соответствующей текущему терминалу (с использованием значения $ COLUMNS, ioctl (2), если доступно, или возврата к 80 символам, если ни один не доступен).

То есть он переопределяет как значение, так COLUMNSи ioctlзначение. Я предпочитаю не полагаться на изменение COLUMNS(хотя это работает здесь), поскольку его значение обновляется динамически каждый раз, когда изменяется размер окна.

Использование MANWIDTHвместо COLUMNSпозволяет также сделать изменение постоянным, добавив строку, например, в export MANWIDTH=60файл запуска оболочки.

Марсель М
источник
Отличная работа. Я тоже не хотел менять КОЛОННЫ, и MANWIDTH работает в RHEL5. Приветствия.
Фелипе Альварес
1
Примечание для читателей: вам может понадобиться использовать export MANWIDTH=60эту настройку в своем ~/.bashrc. См. Stackoverflow.com/a/30173376/82216 . Кроме того, рассмотрите manвозможность включения функции для установки MANWIDTH в зависимости от ширины вашего терминала, как предлагается здесь на вики Arch.
Сампаблокупер
@Marcel M Спасибо за ваш очень точный ответ. Не могли бы вы прочитать обновление в вопросе и отредактировать свой ответ, включив в него основополагающее предложение export MANWIDTH=60?
BowPark
@BowPark Я написал ответ без, exportпотому что вы спросили о временном решении: «Как изменить максимальную ширину линии при создании выходного файла? » ( Выделено мое). Вы можете даже отменить редактирование, поскольку оно не добавляет вопроса. (Комментарий более уместен.)
Марсель М
@MarcelM На самом деле вы правы. Я отредактировал вопрос соответственно. Я написал вторую редакцию с exportзаявлениями, потому что в комментарии это было бы почти нечитаемо (не было возможности создавать новые строки).
BowPark
10

Попробуйте установить COLUMNSпеременную среды. Работы для меня с manот mandb2.7.0.2 на Debian с 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 ...

С версией на Ubuntu 14.04 мне нужно написать это:

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

Там, manпохоже, игнорируется COLUMNSпеременная окружения, если stdin является терминалом (затем он запрашивает у терминального устройства ширину терминала).

Вы также можете попробовать:

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

Ваш не может найти символ с входным кодом ошибки были , потому что вы использовали -Tasciiвместо -Tutf8и не использовать -kдля предварительной обработки файлов с preconv.

Стефан Шазелас
источник
Я попробовал ту же команду:, COLUMNS=60 man apropos | headно, к сожалению, ширина вывода равна всей ширине экрана. Могу ли я установить переменную в COLUMNSдругом месте или другим способом?
BowPark
2
Попробуй COLUMNS=60 < /dev/null man apropos | head. Похоже на Ubuntu 14.04, он не доверяет, COLUMNSесли stdin является терминалом (и получает ширину от терминального устройства).
Стефан Шазелас
Может быть, это так, как вы и предполагали. И теперь это работает, спасибо!
BowPark
4

Вы можете использовать fmtкоманду, которая, насколько мне известно, присутствует в любом дистрибутиве Linux.

man apropos | fmt -w 70 

обернут строки в 70 символов.

dr_
источник
1
да, у меня есть это, спасибо, это работает, и это довольно полезно, но мне нужен обоснованный текст, и вместо этого просто заключаются строки.
BowPark
Извините, я, должно быть, пропустил эту часть.
Dr_
2

Ты можешь использовать 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'
Fiximan
источник
1
Спасибо, я попробовал ваши примеры, и они работают, но - как написано в комментарии к dr01 - мне нужен обоснованный текст.
BowPark