通过管道传输到sed时,仅处理部分git输出

时间:2019-05-08 02:32:32

标签: bash git shell sed

我想在git checkout命令输出的每一行之前添加一个标签。

www [master] % git checkout master --progress | sed -e "s/^/[tag] -- /"
Already on 'master'
[tag] -- Your branch is up to date with 'origin/master'.

作为上面的输出内容,第一行Already on 'master'不能以[tag] --为前缀。我该如何解决?

2 个答案:

答案 0 :(得分:2)

在unix中,默认情况下,所有进程都被授予两个已经打开的流,它们可以通过它们发送输出-标准输出和标准错误-以及另一个可以接收输入的流-标准输入。您可以将它们视为在过程开始之前已经打开并可用的文件。

这个想法是程序应该将可能由其他程序处理的输出发送到标准输出,并且(与本示例更相关)任何错误或有用的诊断信息都应该发送到标准错误。如果程序旨在过滤数据,则应从标准输入中读取该数据。

在外壳中,管道(|)运算符可用于将命令左侧的标准输出连接到命令右侧的标准输入。在您的示例中,您已经将git的标准输出连接到sed的标准输入。这就是为什么git的某些输出带有前缀的原因。

git通过其标准错误流发出了未加前缀的数据。

为了也过滤git的标准错误流,必须首先通过以下方式告诉外壳程序将此流连接到标准输出流所在的位置:

git checkout master --progress 2>&1

将其通过管道传输到sed时:

git checkout master --progress 2>&1 | sed -e "s/^/[tag] -- /"

... git的所有输出都将加上前缀。

有关2>&1的更多信息,请运行man bash并搜索 REDIRECTION 部分。

答案 1 :(得分:1)

如果您对awk没问题,则可以尝试遵循。如果我正确理解它,则只想将标记字符串添加到其中没有字符串主控符的行中,如果是这种情况,请尝试以下操作。

your_command |  awk '!/master/{$0="[tag]" OFS $0} 1'