答案1
你可以做这样的事情-使用文件描述符:
保存当前输出描述符,以便我们稍后恢复它
exec 3>&1
重定向输出流到流程替代插入标签 - 例如
exec 1> >(paste /dev/null -)
从此时起,任何写入标准输出的进程都会通过paste
在开头插入制表符的命令对该输出进行“过滤”。
完成后,您可以通过恢复保存的文件描述符并关闭临时文件来恢复正常行为
exec 1>&3 3>&-
答案2
我知道这个答案对你来说不是最佳的,但是你可以创建一个具有简单名称的 Bash 函数_
(或任何其他尚未使用的名称),它运行作为参数获取的命令并使用制表符缩进其所有输出。
一个例子:
$ _ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04 LTS
Release: 16.04
Codename: xenial
更复杂的 shell 构造也是可能的,但需要将其作为引用参数或使用转义的特殊字符来给出,以防止在传递给函数之前进行评估。
$ _ 'for x in {1..3} ; do echo $x ; done'
1
2
3
$ _ for x in \{1..3\} \; do echo \$x \; done
1
2
3
该函数的代码仅为:
_(){ eval "$@" |& sed "s/^/\t/" ; return "$PIPESTATUS" ;}
作为副作用,这会将 STDERR 合并到 STDOUT 中以便缩进两者,但另一方面它还保留了给定命令的退出状态。
您可以将上面这一行附加到您的~/.bashrc
文件中,以便它可以在用户的所有 Bash 会话中可用。
此答案的先前版本建议使用下面的函数,但这不会缩进 STDERR 流,也不会在给定命令失败时抑制返回/退出代码。此外,由于错误的$*
变量扩展而不是,它会破坏带有引号或大量空格的命令"$@"
,并且可能存在更多问题...
_(){ sed "s/^/\t/" <($*); }
答案3
答案4
我发现了一个更简单的方法:
your-command | paste /dev/null -
从man paste.1
:
将由每个文件中按顺序对应的行(以 TAB 分隔)组成的行写入标准输出。