【问题标题】:Is there any way to tell apart multiple multi-line outputs from a script?有没有办法从脚本中区分多个多行输出?
【发布时间】:2019-10-18 14:41:58
【问题描述】:

我正在运行一个具有多个多行输出的脚本 input.sh,如下所示:

echo -e 'first \n second'
echo -e 'first \n second'
echo -e 'first \n second'

我无法控制这个文件,我只知道它会有多个多行输出。

我需要能够在该文件输出消息时实时对该文件的每个单独输出进行操作。缓冲是一个问题,但不是我在这里要问的问题。

我正在简化一点,但我的问题归结为:我想在每个单独的输出末尾插入一个袋鼠。请参阅下面的尝试:

./input.sh | sed 's/$/kangaroo/'

上面的这个版本在每个换行符之后插入一个袋鼠,而不是每个多行输出。

./input.sh | perl -0777 -pe 's/$/kangaroo/'

此 perl 版本仅在所有输出完成后插入一只袋鼠(总共一只袋鼠,而不是每次输出一只袋鼠。)

我尝试过其他变体,但总是一个或另一个——每一个新行后面都有一个袋鼠,或者每件事后面都有一个袋鼠。我尝试使用tr 将新行替换为表单提要,但这并没有任何区别。

如何做到这一点?

顺便说一句,我已经仔细阅读了this question 及其答案,但他们正在讨论对文件进行操作。我无法将那里描述的原则应用于管道并从标准输入读取。

【问题讨论】:

  • 您可以控制脚本的执行吗?换句话说,您是否可以控制执行input.sh 的脚本?您可以在执行期间修改脚本吗?
  • 是的,但实际上我正在处理许多内容不可预测的脚本。 Input.sh 是代表许多 bash、python 或 ruby​​ 脚本的替身。
  • 你到底想对这个输出做什么?与其抽象问题并要求一个非常狭窄的理想,为什么不发布您的实际输入和期望的输出?
  • 我试图区分脚本中的各个输出,就这么简单。我想和他们做一些与问题完全无关的事情。我不明白告诉您我希望对这些多行输出应用哪些转换会有所帮助,因为它与上述问题无关。
  • 当我想到您可能想要做的事情时,首先想到的是:测量脚本中命令的响应时间。这是你更高层次的目标吗?

标签: bash perl unix sed pipeline


【解决方案1】:

没有;在一般情况下,没有办法可靠地判断两个字节是分别输出并缓冲在一起,还是一起输出。

【讨论】:

  • 我的意思是说有道理,但我非常想相信这不是真的。真的没有办法通过管道对单个多行序列进行操作吗?这似乎是一件非常有用的事情。能够通过管道而不是单独的行来放置段落有无数的用途......
  • 也许你可以在每个添加kangaroo的外部命令之后注入一个管道,如果它看到的最后一个输出不是kangaroo在一个永恒的循环中。不可靠,但可能相当准确。
  • 非常抱歉,但我不太明白你的意思。你能澄清一下这个建议吗?就目前而言,听起来每隔一行都会是袋鼠。
  • tail -f只有当你从文件句柄中画一个空白时,打印kangaroo,然后再次轮询并等待直到你收到新的输入。
  • read() 返回零字节时,表示您已用尽缓冲区。看tail的出处。
【解决方案2】:

没有办法区分

echo -e 'first\nsecond'
echo -e 'first\nsecond'
echo -e 'first\nsecond'

来自

echo -e 'first\nsecond\nfirst'
echo -e 'second\nfirst\nsecond'

两者都输出以下字节流(以十六进制表示):

66 69 72 73 74 0A 73 65 63 6F 6E 64 0A 66 69 72 73 74 0A 73 65 63 6F 6E 64 0A 66 69 72 73 74 0A 73 65 63 6F 6E 64 0A

流不包含有关这些字节的含义或它们如何组合的任何信息。充其量,可能存在时间差异。

【讨论】:

    【解决方案3】:

    你需要一个技巧。

    您可以尝试使用自己的包装器来否决echo 命令!

    echo() {
       printf "%skangeroo\n" "$(/bin/echo $@)"
    }
    
    echo -e 'first \n second'
    echo -e 'first \n second'
    echo -e 'first \n second'
    echo "=================="
    echo -e 'first \n second \n first'
    echo -e 'second \n first \n second'
    

    结果:

    first
     secondkangeroo
    first
     secondkangeroo
    first
     secondkangeroo
    ==================kangeroo
    first
     second
     firstkangeroo
    second
     first
     secondkangeroo
    

    【讨论】:

    • 问题是不是所有的输出都来自echo....我正在运行运行其他进程的脚本,所以输出只是有时来自echo,通常是输出一个二进制文件。
    • 在这种情况下,@tripleee 的评论(查找输出块)可能会有所帮助。也许更改您的要求更容易:还有其他方法可以找到您想要的吗?查找所有多行输出并查看最后一行 (sed 's/.*second.*/&kangeroo/') 中的内容,您是否总是有 2 行输出,或者您是否也可以在二进制文件周围编写一个包装器 (mv my_prog my_prog.org 并在脚本 my_prog,完成后还会添加一个袋鼠)?
    猜你喜欢
    • 2021-07-05
    • 1970-01-01
    • 2022-01-08
    • 2017-03-29
    • 2021-02-01
    • 2013-08-01
    • 2015-03-20
    • 2021-09-30
    • 1970-01-01
    相关资源
    最近更新 更多