根据长度将命令的输出输入less或into cat

时间:2009-10-14 14:14:52

标签: shell zsh pager

首先,让我说明这是一个编程问题(因此不属于超级用户 et al。)因为我在谈论shell编程。这可能几乎是一个高尔夫问题,但我没有答案开始,所以任何帮助将不胜感激: - )

所以,故事是:我喜欢使用less选项将内容输入--quit-if-one-screen,因为它非常舒适:less在不必要的时候不会妨碍我。或者是吗?当我的提示已经在终端窗口的底部时,此选项完全符合我的要求(即less表现得像cat)。但是,当我当前的提示位于窗口的顶部时,less首先打印大量空行以清除屏幕,然后在底部打印出我的(短)文件。屏幕,然后才意识到文本少于一个屏幕,所以它退出并且我得到了提示。

但是这种行为并不是很好,因为所有那些无用的空白行。我尝试了不同的选项,或编写脚本和别名,我能想到的最好的就是这个(我使用的是zsh,所以shell已经能够复制管道等等):

function catless() {
 cat   \
  >>( bucket -$LINES | cat  ) \
  >>( bucket +$LINES | less )
}

bucket是我刚写的另一个脚本,如果它小于N行(带-N)或者超过N行,则将 stdin 复制到 stdout N(带+ N)。 我在这里发布了它:http://snipt.net/Gyom/copy-stdin-to-stdout-or-not-depending-on-length

ls | catless差不多了。但是,出于同步原因,此处涉及的不同进程无法正确访问终端,并且所有内容都在后台执行(特别是,我从未在此处获得正确的less,并且提示会很快返回)。但也许我走错了路。

因此,总而言之,我想要的是这样一个函数/脚本/我可以键入ls | catless的任何内容,当{的输出ls | cat时,它的行为完全 {1}}比一个屏幕短,而ls更长。

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

-X标志可能会帮助你(从少(1)):

  -X or --no-init
         Disables sending the termcap initialization and deinitialization
         strings to the terminal.   This  is  sometimes desirable if the
         deinitialization string does something unnecessary, like
         clearing the screen.

所以,以下应该做你想做的事:

export LESS="-E -X"

或者,既然你喜欢-quit-if-one-screen,你可以改为:

export LESS="-F -X"

答案 1 :(得分:1)

less有一个--clear-screen选项(也可用-c。您可能需要检查您的$ LESS环境变量,以确保它包括那个选项。我没有,它的行为与你想要的完全一样(不是你想要克服的)。

您可以使用+ ad hoc 基础上禁用$ LESS变量中设置的选项。例如:

less -+c shortfile

您还应确保$TERM设置正确。

如果所有其他方法都失败了,请查看$LESSOPEN的“输入预处理器”部分中的$LESSCLOSE预处理器和man less后处理器功能,看看是否会引导您进入另一个方法

答案 2 :(得分:1)

news for less version 406中,我看到“请勿在第一页上移至屏幕底部。”。你有哪个版本?我的系统版本是382,它在打印前移动到屏幕的底部(如果只有一个屏幕,并且使用了-F,则会产生空白行。)

我刚刚安装了版本436,它似乎在给定-FX时做了你想做的事情(把它放在LESS env var和你的其他prefs中,让任何东西使用这些prefs只需运行{ {1}})。

如果您无法获得新版本,可以尝试这样做:

less

关键是shell必须知道文件中的行数是否比之前的屏幕(可能)启动function catless() { local line buffer='' num=0 limit=$LINES while IFS='' read -r line; do buffer="$buffer$line"$'\n' line='' num=$(( num+1 )) [[ $num -ge $limit ]] && break done if [[ $num -ge $limit ]]; then { printf %s "$buffer$line"; cat } | less else printf %s "$buffer$line" fi } 更多(您最初使用的多重技术只能在背景)。如果shell内less对你来说不够健壮,你可以通过重新编写代码来替换它:

read