缩进Bash脚本输出

20

我正在尝试编写一个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.

目前,所有内容都是压缩的,没有缩进。 有人知道怎么做吗?我尝试使用 sed awk ,但似乎没有比 Initialized empty Git repository in /root/client_scripts/jojo/.git/ 更多的输出。 我非常感谢任何评论。

5个回答

48

通过管道传递

sed "s/^/    /g"

这将用四个空格代替行首的(零宽度)锚点,实际上在行首添加了四个空格。

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


如果您想要的话,也可以在其中放置一个字面制表符。 - Carl Norum
使用I/O重定向来捕获标准错误流。 - David Harris
@Topher:命令 1>临时文件 2>&1 将会把 STDOUT 和 STDERR 捕获到临时文件中。命令 1>输出文件 2>错误文件将会把 STDOUT 捕获到输出文件中,而 STDERR 则捕获到错误文件中。 - David Harris
3
对于原来只应用于第一行的缩进问题,您需要在 sed 字符串末尾添加“g”:sed 's/^/ /g' - Luis E.
@LuisE.,我的理解是正则表达式替换是针对每一行单独执行的,而不是在整个输出上执行一次。而且你只能替换一个^,所以没有/g应该没问题。 - Joey
显示剩余4条评论

9

一种不需要使用sed的不同解决方案:

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

你缺少了读取变量;修复:`comand | while read REPLY; do echo " $REPLY"; done' - Ryan Bright
3
不,阅读Bash手册,REPLY变量是隐含的。或者在shell中键入此命令并进行测试。 - Juliano

7
将git的输出通过任何命令进行管道传输的问题在于,git会检测到输出不是终端,因此它不会输出进度消息。通常情况下,将大量终端字符和进度更新输出到非终端设备是没有用处的。
为了获取进度消息,您需要在git clone中提供--verbose选项。进度消息出现在stderr上,因此您可能需要像2>&1 | ...一样使用管道。
请注意,进度消息不会逐行显示,而是会获得许多终端转义代码,这些代码旨在清除同一行。尝试通过类似sed的基于行的工具对此输出进行缩进很可能会很困难,甚至是不可能的。对于可以无缓冲区处理输入的程序,应该可以在输出中查找^M并在其后立即添加一些空格(或制表符),每批数据接收时刷新一次。

1
感谢提供的信息,然而,无论是我的 git 版本(1.5.6.5)还是最新版本,都没有 --version 选项,无论是在 git 还是 git-clone 中。我想如果我想要这样做,我只能认命了。感谢关于 git 检测它不在终端上的信息。 - Topher Fangio
嗯...我刚刚重新阅读了我的上一条评论,我真的是说的--verbose而不是--version - Topher Fangio

6
你可以通过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所需的输出。仍然只输出第一行... - Topher Fangio

4
自从awk解决方案尚未发布:
$ echo -en "hello\nworld\n"
hello
world
$ echo -en "hello\nworld\n" | awk '{print "    "$0}'
    hello
    world

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接