bash one-liner для открытия `less` на последнем экране без временных файлов
Я пытаюсь создать однострочник для открытия less
на последнем экране многоэкранного вывода из стандартного ввода. Причина в том, что я работаю над программой, которая производит длинный AST
и я должен быть в состоянии пройти вверх и вниз по нему, но я бы предпочел начать с нижней части. Я придумал это:
$ python a.py 2>&1 | tee >(lines=+$(( $(wc -l) - $LINES))) | less +$lines
Во-первых, мне нужно вычислить количество строк в выводе и вычесть $LINES
по нему я знаю, какая верхняя строка последнего экрана. Мне нужно будет повторно использовать a.py
выходной позже, поэтому я использую tee
с заменой процесса для этой цели. В качестве последнего шага я указываю less
открыть оригинальный stdout на определенной линии. Конечно, это не работает в Bash
так как $lines
не устанавливается на последнем шаге, так как каждая подкоманда выполняется в подоболочке. В ZSH
, хотя команды конвейера не выполняются в подоболочке, подстановка процесса все еще есть, и поэтому она также не работает. Это не домашнее задание или работа, мне просто интересно, можно ли делать то, что я хочу, не создавая временный файл в Bash
или же ZSH
, Есть идеи?
2 ответа
Реальный ответ на ваш вопрос должен быть вариант +G
в less
, но вы указали, что определение проблемы не является представительным для абстрактной проблемы, которую вы хотите решить. Поэтому, пожалуйста, рассмотрите эту альтернативную проблему:
python a.py 2>&1 | \
awk '
{a[NR]=$0}
END{
print NR
for (i=1;i<=NR;i++)print a[i]
}
' | {
read -r l
less -j-1 +$l
}
awk
Команда печатает количество строк, а затем все строки в последовательности. Мы определяем первую строку, чтобы содержать некоторую метаинформацию. Это передано группе команд, разделенных {
а также }
, Первая строка занята read
, который хранит его в переменной $l
, Остальные строки заняты less
где эта переменная может быть использована. -j-1
используется, поэтому совпадающая линия находится внизу экрана.
less
поддерживает это врожденно. +
синтаксис, который вы используете, принимает меньше команд, которые вы можете ввести во время работы, включая G
для конца.
... | less +G
делает именно то, что вы хотите.
Это на самом деле явно упоминается в качестве примера на странице руководства (поиск "+G").