【问题标题】:Indenting Bash Script Output缩进 Bash 脚本输出
【发布时间】:2010-12-12 20:05:51
【问题描述】:

我正在尝试编写一个 bash 脚本,但很难使输出看起来整洁有序。我可以只使用换行符,但我更希望输出易于阅读。例如,当我运行git clone ... 时,我想先回显“克隆存储库”,然后将git 的输出缩进。示例输出:

Cloning repository...
    Initialized empty Git repository in /root/client_scripts/jojo/.git/
    remote: Counting objects: 130, done.
    remote: Compressing objects: 100% (121/121), done.
    remote: Total 130 (delta 13), reused 113 (delta 6)
    Receiving objects: 100% (130/130), 176.07 KiB, done.
    Resolving deltas: 100% (13/13), done.

目前,它都是压缩的,没有缩进。有谁知道如何做到这一点?我尝试使用sedawk,但它似乎没有显示比Initialized empty Git repository in /root/client_scripts/jojo/.git/ 更多的输出。我将非常感谢任何 cmets。

【问题讨论】:

    标签: git bash scripting indentation


    【解决方案1】:

    通过管道

    sed "s/^/    /g"
    

    这会将行首的(零宽度)锚点替换为四个空格,有效地在行首添加四个空格。

    (g 全局执行此操作;没有它,它只会执行一次,这将执行第一行。)

    【讨论】:

    • 如果你想要的话,你也可以在里面放一个文字制表符。
    • 我已经尝试过了,不幸的是,它只输出第一行(“Initialized empty...”)。我的猜测是其余信息输出到 STDERR,但我似乎无法弄清楚如何重定向它。
    • 使用 I/O 重定向捕获 STDERR
    • @Topher:快速确定标准输出的方法是command | less:less 只会捕获标准输出,您不会看到任何进入标准错误的内容。好吧,它可能会显示,直到您按 j/k/up/down 来“刷新”页面。
    • 对于最初的缩进问题仅适用于第一行:您必须在 sed 字符串的末尾附加一个“g”:sed 's/^/ /g'
    【解决方案2】:

    您可以通过 sed 过滤要缩进的命令的输出。

    /tmp/test>cat script
    #!/bin/sh
    
    echo "Running ls -l"
    ls -l 2>&1 | sed 's/^/\t/'
    
    /tmp/test>sh script
    Running ls -l
            total 4
            -rw-rw-r-- 1 hlovdal hlovdal 55 2009-11-03 23:36 script
    /tmp/test>
    

    sed 命令将用制表符替换行首(第一个字符之前),即在行首插入制表符。

    更新为也缩进标准错误。

    【讨论】:

    • 不幸的是,这没有从 git 捕获必要的输出。仍然只输出第一行...
    【解决方案3】:

    不需要 sed 的不同解决方案:

    command | (while read; do echo "    $REPLY"; done)
    

    【讨论】:

    • 您缺少读取变量;修复:`命令|在阅读回复时;做回声“$回复”;完成'
    • @Ryan Bright:不,阅读 Bash 手册,REPLY 变量是隐含的。或者只是在 shell 中输入它并自己测试它。
    【解决方案4】:

    由于 awk 解决方案尚未发布:

    $ echo -en "hello\nworld\n"
    hello
    world
    $ echo -en "hello\nworld\n" | awk '{print "    "$0}'
        hello
        world
    

    【讨论】:

      【解决方案5】:

      通过任何命令管道输出 git 的问题是 git 会检测到输出不是终端,因此它不会输出进度消息,因为(通常)管道很多没有用终端字符和进度更新到不是终端的东西。

      无论如何,要获得进度消息,您需要向git clone 提供--verbose 选项。进度消息显示在stderr 上,因此您可能需要类似2>&1 | ... 的管道。

      请注意,进度消息不会逐行显示,但您会得到很多旨在清除同一行的终端转义码。尝试通过管道通过像 sed 这样的基于行的工具来缩进这个输出可能会很困难,如果不是不可能的话。对于可以处理无缓冲输入的程序,应该很可能在输出中查找^M 并立即在后面添加一些空格(或制表符),并在收到每批数据时刷新频率。

      【讨论】:

      • 感谢您的信息,但是,我的 git (1.5.6.5) 版本和最新版本都没有 --version 作为 git 或 git-clone 的选项。如果我想这样做,我想我只是不走运。感谢您提供有关 git 检测到它不在终端上的信息。
      • Err...我刚刚重读了我之前的评论,我的意思是--verbose 而不是--version
      猜你喜欢
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-15
      • 2018-05-18
      相关资源
      最近更新 更多