首先,让我指出这是一个编程问题(因此不属于superuser等),因为我在说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行(带有+ N),它将stdin复制到stdout。我在这里张贴:http://snipt.net/Gyom/copy-stdin-to-stdout-or-not-depending-on-length
ls | catless
几乎可以正常工作。但是,出于同步的原因,此处涉及的不同进程无法正确访问终端,并且所有操作均在后台执行(特别是,我在此处从未获得正确的less
,并且提示返回的太早了)。但是也许我走了错误的道路。因此,总而言之,我想要的是这样的一个函数/脚本/无论我可以键入
ls | catless
,并且当ls | cat
的输出短于一个屏幕时,它的行为与ls
完全相同,而当它的输出长于一个屏幕时,其行为与ls | less
完全相同。有任何想法吗 ?
最佳答案
在news for less version 406中,我看到“不要移动到第一页的屏幕底部。”。您有哪个版本?我的系统版本是382,在打印之前它移到屏幕底部(如果只有一个screenful并且使用-F
,则会引起空白行)。
我刚刚安装了436版,在给定-FX
时,它似乎可以满足您的要求(将其与其他首选项一起放入LESS
env var中,使任何东西都可以通过运行less
来使用这些首选项)。
如果无法获得新版本,则可以尝试以下方法:
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
(最初使用的multi-io技术只能在后台运行内容)之前,必须知道文件中的行是否比屏幕上的行多。如果 shell 内read
对您而言不够健壮,则可以通过稍微修改代码来替换它:function cat_up_to_N_lines_and_exit_success_if_more() {
# replace this with some other implmentation
# if read -r is not robust enough
local line buffer='' num=0 limit="$1"
while IFS='' read -r line; do
buffer="$buffer$line"$'\n'
line=''
num=$(( num+1 ))
[[ $num -ge $limit ]] && break
done
printf %s "$buffer$line"
[[ $num -ge $limit ]]
}
function catless() {
local limit=$LINES buffer=''
# capture first $limit lines
# the \0 business is to guard the trailing newline
buffer=${"$(
cat_up_to_N_lines_and_exit_success_if_more $limit
ec=$?
printf '\0'
exit $ec)"%$'\0'}
use_pager=$?
if [[ $use_pager -eq 0 ]]; then
{ printf '%s' "$buffer"; cat } | less
else
printf '%s' "$buffer"
fi
}
关于shell - 将命令的输出根据长度通过管道传递到更少或猫,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1566528/