【问题标题】:bash one-liner for opening `less` on the last screen w/o temporary filesbash one-liner 用于在没有临时文件的最后一个屏幕上打开“less”
【发布时间】:2016-01-07 22:35:06
【问题描述】:

我尝试在来自标准输入的多屏幕输出的最后一个屏幕上创建一个用于打开less 的单行。这样做的原因是我正在开发一个产生长 AST 的程序,我需要能够上下遍历它,但我更愿意从底部开始。我想出了这个:

$ python a.py 2>&1 | tee >(lines=+$(( $(wc -l) - $LINES))) | less +$lines

首先,我需要计算输出中的行数并从中减去$LINES,这样我就知道最后一个屏幕的最上面一行是什么。稍后我将需要重用a.py 输出,因此我将tee 与进程替换一起用于此目的。作为最后一步,我指向less 在特定行上打开原始标准输出。当然,它在Bash 中不起作用,因为在最后一步中没有设置$lines,因为每个子命令都在子shell 中运行。在ZSH 中,即使管道命令不在子shell 中运行,进程替换仍然存在,因此它也不起作用。这不是家庭作业或工作任务,我只是想知道是否可以在不创建BashZSH 的临时文件的情况下做我想做的事情。有什么想法吗?

【问题讨论】:

  • 为什么python不告诉你它写了多少行?大概可以算……
  • 这不应该被迁移。
  • 有关通用计算硬件和软件的问题对于 Stack Overflow 来说是题外话,除非它们直接涉及主要用于编程的工具。您可以通过Unix & Linux 获得帮助。
  • @Gilles:有趣的是我在 U&L 上问了这个问题,它被迁移到了这里。
  • 我也不明白为什么要迁移它=s

标签: bash pipe zsh less-unix


【解决方案1】:

less 天生就支持这一点。您正在使用的 + 语法在它运行时接受您可以输入的任何较少的命令,包括用于 go-to-end 的 G

... | less +G

完全按照你的意愿去做。

这实际上是mentioned explicitly as an example in the man page(搜索“+G”)。

【讨论】:

  • 酷,谢谢,我一定错过了。它完全解决了我的问题,但只是好奇你知道没有+G 的任何方法吗?我知道这有点毫无意义,但我只是想确保如果没有从更有经验的用户那里创建临时文件是不可能的。
  • 如果您对在管道中设置变量有疑问,我建议您 ask 明确地使用该上下文的新变量。至少它可能是依赖于 shell 的。
  • 我用BashZSH 标记了这个问题,因为我只对这两个感兴趣。我认为在管道中设置变量在Bash 中设计是不可能的,并且在ZSH 中的某处使用进程替换时也是不可能的。恐怕这样的问题可能不会受到更多的关注。这个问题非常具体,但实际上它归结为在子shell中设置变量,所以一个理想的解决方案是完全避免子shell,但我不知道如何做到这一点,或者它是否可能。
【解决方案2】:

您问题的真正答案应该是+Gless 选项,但您指出问题定义不能代表您要解决的抽象问题。因此,请考虑这个替代问题:

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,因此匹配的行位于屏幕底部。

【讨论】:

  • 很好,我了解到可以使用 readstdin 保存变量,如下所示:echo one two | { read l; echo $l ;}。但是,我不确定这将如何处理不完全由数字组成的输出,因此它对我的特定问题没有用,但无论如何都很好。
  • @user1042840:尝试用python a.py 2&gt;&amp;1 替换第一个for-loop。 awk's print NR 将使元数据成为可用的数字,无论输入如何。
  • 我自己做的,因为我必须承认这可能令人困惑。试试当前的命令。
  • 你明白了。通过以某种方式滥用第一行来解决文本流中缺少元数据的问题是一个丑陋的黑客:)
  • 如果总数据加上开销超过可用内存,这将崩溃或死亡或两者兼而有之。 awk 可以使用 '{a[NR]=$0;} END{ for(i=1;i&lt;=NR;i++) print a[i] | "less -j-1 +" NR }' 运行“更少”。
猜你喜欢
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多