sed
не подходит для этой задачи
… но это не значит, что вы не можете злоупотреблять им, чтобы выполнять свои торги:
sed -n -e "2,$ p" -e "/^~keyword~./ {s/$/§/;p}" in.txt | sed -n '/^~keyword~./,/^~[[:alpha:]]./ {/^~keyword~..*§$/ {s/§$//; b print}; /^~[[:alpha:]]./b; :print p}'
Итак, полежав в темной комнате ненадолго, чтобы оправиться от этой мерзости, вот что он делает:
Чего мы хотим достичь?
Извлекаем «блоки» из файла, где каждый «блок» начинается со строки, соответствующей регулярному выражению R1 («начальные строки»), и заканчивается строкой, предшествующей следующему появлению регулярного выражения R2 («завершающие строки»).
Так что просто используйте диапазоны шаблонов sed
, в чем проблема?
R2 - это подмножество R1, поэтому наши «линии-ограничители» могут быть началом новых блоков. sed
не поддерживает перекрывающиеся блоки.
Итак, создайте регулярное выражение, которое соответствует R2, но не соответствует R1.
Для этого потребуются утверждения нулевой длины, которых нет в sed
. (Помните, как я сказал, что sed
не был подходящим инструментом для этого?)
Решение: если поиск «линии терминатора» поглощает «начальные строки», просто продублируйте «начальные строки» .
Это сработает, но мы не должны дублировать первую «начальную строку», иначе мы просто увидим каждую повторяющуюся пару как блок. 1
sed -n -e "2,$ p" -e "/^~keyword~./ {s/$/§/;p}" in.txt
= Распечатать все строки, начинающиеся со строки номер 2 (т.е. все, кроме строки 1). Также выведите строки второй раз , если они соответствуют R1. Я перейду к s / $ / § /
чуть позже.
Теперь, когда у нас есть четко разделенные блоки, используйте диапазон шаблонов для печати всех строк, заключенных между началом блока и признаками конца: sed -n '/^~keyword~./,/^~[[:alpha :]] ./ p '
Ой, подождите, это включает в себя линии терминатора. Stack Overflow спешит на помощь .
Но мы не можем просто пропустить все строки, соответствующие R2 - помните, что R1 ⊂ R2, поэтому удаление строк-терминаторов приведет к удалению и начальных строк.
«К счастью», sed
имеет ветвление.Как насчет того, чтобы напечатать все, что соответствует R1, и отбросить только совпадения для R2 , затем ?
sed -n '/^~keyword~./,/^~[[:alpha:]]./ {/^~keyword~./b print; /^~[[:alpha:]]./b; :print p}'
Отлично, теперь мы печатаем наши дублированные начальные строки, когда они оказываются строкой-ограничителем ... Если бы только там было способ отличить исходные начальные строки от их дубликатов…
Вот почему у нас было s / $ / § /
: добавить §
в конце каждого дублированного начала строка (обратите внимание, что дублированные §'ы дублированные начальные строки в конечном итоге будут теми, которые начинают блок, а не-§'Ed начальные строки будут теми, которые ограничивают блоки, за которыми сразу же следует другой блок).
Теперь у нас есть вся информация, необходимая для более детальной проверки и ветвления:
Для всех строк в диапазоне блоков…
{/^~keyword~..*§$/ {s/§$//; b print}; /^~[[:alpha:]]./b; :print p}
Конечный результат:
sed -n -e "2,$ p" -e "/^~keyword~./ {s/$/§/;p}" in.txt | sed -n '/^~keyword~./,/^~[[:alpha:]]./ {/^~keyword~..*§$/ {s/§$//; b print}; /^~[[:alpha:]]./b; :print p}'
Однако это предполагает, что первая начальная строка файла (соответствующая R1) находится в строке 1 (помните, что это единственная строка, которую мы исключили при дублировании начальных строк). В противном случае вы получите аккуратные пары, но не данные:
~keyword~, ~output~.
~keyword~, ~output~.
Возможно, вы могли бы добавить больше сопоставлений и ветвлений, чтобы обойти это, но на самом деле…
просто используйте awk
.
У меня есть пара несовершенных, но, возможно, полезных идей.
Используйте полосу прокрутки терминала.
Подробности (при условии xterm
; для других терминалов потребуются настройки.)
xterm
он находится в меню, которое вы получаете с помощью Ctrl + Button2.) less
не работает с параметром -c
(I включили эту опцию в моей переменной окружения LESS
, но она мешает тому, что мы собираемся делать, поэтому мне нужно ввести -c
, чтобы выключить ее.) less
, которые вам нравятся, прокрутите вверх или вниз, чтобы первая строка, которую вы хотите скопировать, была видна на экране. /
- суть здесь в том, чтобы получить на меньше
для отправки всех строк на терминал, чтобы их можно было скопировать . Возможная трудность: ваш буфер обратной прокрутки может быть недостаточно большим.Это можно изменить в xterm
с помощью ресурса saveLines
или параметра командной строки -sl
, но я не знаю способа изменить его в xterm это уже работает.
Используйте команду |
(вертикальная черта) в less
, чтобы отправить текст в xclip
.
Подробности:
less
, которые вам нравятся, прокрутите вверх или вниз, чтобы поместить последнюю строку, которую вы хотите скопировать, вверху экрана. Вы можете пропустить этот шаг и следующий шаг, если хотите скопировать до конца. m
(отметка), чтобы установить отметку в выбранной конечной позиции. Метки сами по себе являются полезной функцией, и вы должны знать их уже из vi
, но на всякий случай вы этого не сделаете: m x устанавливает метку, где x
может быть любой буквой, а ' x вернет вас туда позже. x
должно быть той же буквой отметки, которую вы использовали в команде m
, или $
для «до конца». Введите там xclip
. Простой случай копирования всей страницы руководства сводится к g | $ x c l i p Enter .
Предупреждение (т. Е. ужасная вещь, которая только что произошла со мной ): xclip
будет полу-фоновым, запущенным как часть группы процессов less
. Если вы попытаетесь приостановить меньше
, запустить другое задание на том же терминале и вставить в него данные, это не сработает. Затем, когда вы позже поставите на передний план задание man
/ less
, паста внезапно выйдет наружу. Я думаю, это следует рассматривать как ошибку xclip
...
Как указано на Nixcraft :
Получить xclip
:
sudo apt-get install xclip
или
yum install xclip
в системе на основе RPM.
человек мужчина | your_magic_here | xclip -selection clipboard
-выборный буфер обмена
, чтобы вместо этого выбрать вставку средним щелчком мыши (так называемый первичный выбор). Обратите внимание, что your_magic_here
- это заполнитель для текстового фильтра ( sed
/ awk
/ perl
/ ...), который выбирает желаемую часть справочной страницы в соответствии с вашим конкретным вариантом использования, который вы не описали, поэтому, боюсь, я не могу привести конкретный пример.
Терминальный мультиплексор, такой как tmux
или screen
, обычно имеет подобную функциональность (то есть, чтобы сохранить часть буфера прокрутки в файл или передать его какой-либо команде), и их использование обычно в любом случае хорошая идея, так что вы можете взглянуть на один из них.
Предполагая, что вы используете gnome-terminal
и less
в качестве пейджера для man
вы можете:
less
для man
с помощью клавиши -X
, чтобы отключить альтернативный экран, например: LESS = - X man less
Это позволит добавить вывод man
в буфер истории эмулятора терминала. Подробнее см. В этом ответе https://unix.stackexchange.com/a/38638/87918 .
gnome-terminal
, начиная с последней страницы до первой, перетащив мышь к верхнему краю окна. Подробный процесс выделения текста описан здесь : Это не работает в Gnome Terminal. Вместо этого вам нужно начать выделение левой кнопкой мыши и, делая это, перетащить курсор мыши к краю окна (или за пределы окна ). G-T будет прокручивать элементы за вас, расширяя выбор в процессе. Прокрутка G-T выполняется достаточно быстро, поэтому это достаточно удобный и интуитивно понятный процесс, возможно, лучше, чем у xterm.
Это зависит от вашей терминальной программы, но большинство терминальных программ не имеют функции сохранения выделенного текста.
LXTerminal, uxterm, Konsole и GNOME Terminal, кажется, лишены этой "функции", но могут быть и другие, у которых она есть. Посмотрите на структуру меню вашей терминальной программы, возможно, там есть что-то вроде "Сохранить выделенное"
Используйте | (pipe )команда в меньшем количестве с метками, как ответил Wumpus Q. Wumbley в его втором варианте , но перенаправление с использованием tee для добавления к уже существующему файлу для этой цели:
|tee >> ~/helpaggregator.txt
Я предлагаю существующий файл, так как при изучении новых команд обычно приходится сверяться с ними, и желательно, чтобы они были объединены. Кроме того, автодополнение табуляции пригодится.