/ dev / vcs [a]
даст вам только последний полный экран, даже если вы прокрутили вверх, но выбор ioctl ()
s, используемый gpm
, позволит вам сбросить текущий отображаемый экран даже при прокрутке вверх.
Итак, вы можете:
sleep 3; perl -e '
require "sys/ioctl.ph";
# copy:
ioctl(STDIN, &TIOCLINUX, $arg = pack("CS5", 2, 1, 1, 80, 25, 2));
# paste:
ioctl(STDIN, &TIOCLINUX, $arg = "\3")'; cat > file
Настроить 80 и 25 на вашу фактическую ширину и высоту экрана.
спящий режим 3
дает вам время для прокрутки вверх (с помощью Shift + PageUP ) до фактического экрана, который вы хотите сбросить. cat> file
перенаправляет вставку в файл
. Завершите его, нажав Ctrl + D .
Подробнее см. console_ioctl (4)
.
Если у вас установлен и запущен gpm
, вы можете сделать этот выбор с помощью мыши.
Прокрутка и выбор виртуальной консоли Linux очень ограничены и довольно раздражают (в том смысле, что при переключении консоли вы теряете всю прокрутку). Забегая вперед, я бы посоветовал вам использовать в нем такие вещи, как GNU screen
или tmux
(я лично использую их в еще более функциональных терминалах). С их помощью вы можете иметь более крупные прокрутки с возможностью поиска и легко выгружать их в файлы (и даже регистрировать весь вывод терминала, а также все другие полезности, которые поставляются с этими терминальными мультиплексорами).
Что касается автоматизации процесса сброса всего буфера прокрутки, это должно быть возможно при некоторых условиях, но довольно сложно, поскольку API очень ограничен. Существует недокументированный ioctl
(TIOCLINUX, subcode = 13) для прокрутки текущей виртуальной консоли с некоторым смещением (отрицательное для прокрутки вверх, положительное для прокрутки вниз).
Однако нет способа (насколько я знаю) узнать текущий размер буфера обратной прокрутки. Поэтому трудно определить, когда вы достигли вершины этого буфера. Если вы попытаетесь прокрутить мимо него, экран не сместится так сильно, и нет надежного способа узнать, насколько действительно прокручен экран.
Я также нахожу поведение прокрутки ioctl неустойчивым (по крайней мере, с консолью VGA), когда прокрутка менее чем на 4 строки работает только изредка.
Приведенный ниже сценарий, кажется, работает для меня на консолях с кадровым буфером (а иногда и на VGA) при условии, что буфер обратной прокрутки не содержит последовательностей одинаковых строк длиннее одного экрана плюс одна строка.
Это довольно медленно, поскольку выполняется прокрутка по одной строке за раз, и при чтении каждого дампа экрана требуется 10 мсек ожидания eof.
Для использования как тот-скрипт> файл
из виртуальной консоли.
#! /usr/bin/perl
require "sys/ioctl.ph";
($rows,$cols) = split " ", `stty size`;
$stty = `stty -g`; chomp $stty;
system(qw(stty raw -echo icrnl min 0 time 1));
sub scroll {
ioctl(STDIN, &TIOCLINUX, $arg = pack("Cx3l", 13, $_[0])) or die "scroll: $!";
}
sub grab {
ioctl(STDIN, &TIOCLINUX, $arg = pack("CS5", 2, 1, 1, $cols, $rows, 2)) or die "copy: $!";
ioctl(STDIN, &TIOCLINUX, $arg = "\3") or die "paste: $!";
return <STDIN>;
}
for ($s = 0;;$s--) {
scroll $s if $s;
@lines = grab;
if ($s) {
last if "@lines" eq "@lastlines";
unshift @output, $lines[0];
} else {
@output = @lines;
}
@lastlines = @lines;
}
print @output;
exec("stty", $stty);
Вы можете использовать ed
!
ed -s file1 <<< $'2r !head -10 file2\nw\nq'
Это говорит ed редактировать файл1 тремя командами:
head -10 file2
и вставьте его w
записать файл q
в комплекте В GNU sed (с использованием расширения e
, которое направляет ввод из команды оболочки):
sed -i '3e head -10 file2' file1
Приведенный ниже сценарий представляет собой цикл for
, который повторяет идею ed
столько раз, сколько блоков transcr_
в файле1. Каждый раз в цикле мы вычисляем три элемента:
ed
начала чтения из файла1 sed
начала чтения из файла2 sed
остановки чтения из файла2 Пункт #1 более четко прописан как :10*(N-1) + 2*N
, который я сократил до 12*N - 10
.
Элементы с #2 и #3 более четко обозначены как 10*(N-1) + 1
–10*N
, которые я сократил до 10*N - 9
–10*N
.
Я заменил команду head
на более гибкую и мощную команду sed
для выделения блоков строк из файла2.
Это приведет к перезаписи файла 1 times
раз по мере прохождения цикла.
# how many times we need to insert blocks
times=$(grep -c transcr_ file1)
for((index=1;index <= times; index++));
do
printf "%dr !sed -n %d,%dp file2\nw\nq\n" $((12 * index - 10)) $((10 * index - 9)) $(( 10 * index )) |
ed -s file1
done