我很确定很久以前就在某些同事的系统上看到过这种对 less 命令的定制,以模仿“more”。我想要的是:
如果文件很短(不到一屏长),它的行为应该像 cat:它显示文件的内容并退出。
如果文件长于一个屏幕,它应该像往常一样运行,等待用户输入并在退出时清除屏幕并将先前的命令保留在屏幕上。
我尝试过使用较少的 -FX 进行实验,但对于大文件来说,它会在屏幕上留下大量内容。
答案1
如果我理解正确,您希望保留大文件的备用屏幕切换行为,并仅针对适合单个屏幕且不需要滚动的小文件打开 -X 开关。
现在这是 530 版本中的默认行为less
;NEWS
从文件中引用源代码:
较小版本 487 和 530 之间的主要变化
-F
如果使用和 文件适合一个屏幕,则不要输出终端初始化序列。
不幸的是,截至 2019 年,一些发行版(例如 Debian 10)仍然使用旧版本的less
,因此如果您不想从来源,唯一的解决方案是使用包装器。
这是此类包装器的示例。其已知的局限性是A):n
和:p
(下一个/上一个文件)命令不起作用less
——命令行中的所有文件都连接在一个流中,并且b)它无法处理输入中的空字节,除非/usr/bin/awk
实际上是gawk
(GNU Awk)或 Thomas Dickey 的莫克。
#! /usr/bin/awk -f
BEGIN { "tput lines" | getline max; max -= 2 }
{ l[NR]=$0 }
NR>=max {
for(i = 1; i <= NR; i++) print l[i] | "less";
while(getline > 0) print | "less";
}
END { if (NR < max) for(i = 1; i <= NR; i++) print l[i] | "less -FX" }
答案2
没有简单的方法可以解决这个问题。
您要么less
使用备用屏幕来保持原始屏幕的原始状态,要么不使用(使用-X
)。
您不能真正期望less
将屏幕恢复原样,并在读取整页后开始使用备用屏幕。
我们需要以某种方式等待至少一页或 eof 被读取,然后才能less
以正确的模式启动并发送数据。就像是:
page_stdin() {
awk -v l="${LINES:=$(tput lines)}" '
cmd {print | cmd; next}
{lines = lines $0 ORS}
NR == l {cmd = "less"; printf "%s", lines | cmd}
END {if (!cmd) printf "%s", lines | "less -FX"}'
}
mypager() {
if [ "$#" -eq 0 ]; then
page_stdin
else
for file do page_stdin < "$file"; done
fi
}
(使用 GNU awk
,您可以替换ORS
为,RT
如果一开始就不存在尾随换行符,则不添加)。
但这意味着您不会开始看到管道命令的输出,cmd | mypager
直到有一整页的内容或它完成输出为止。 (例如尝试seq 200 | pv -qL40 | mypager
与 进行比较seq 200 | pv -qL40 | less
)。
请注意,它假设您不使用类似的东西LESS=-s
,并且会被大于屏幕的线条所欺骗,除非您有LESS=-S
。
答案3
将其粘贴到您的终端上(或将其放在 bashrc 上):
less_cat(){
[ "$(wc -l <"$1")" -ge "$LINES" ] && less "$1" || less -FX "$1"
}
现在您应该能够执行:
less_cat /etc/fstab
less_cat /var/log/messages
它会完全按照您的意愿行事。
笔记:该解决方案兼容BASH/ZSH(见评论)
祝你好运!