根据内容将输出重定向到3个不同的文件

时间:2017-04-12 19:22:32

标签: linux bash pipe stdout

我正在运行一些遗留bash代码,并希望插入应该转到stdout的print语句。我想要去stdout的任何内容转到out.out以及转到stderr的任何内容转到err.err

正常运行myCode.sh 2> err.err 1> out.out会将所有内容打印出来,但是我希望放入echo "NewStatement: I am at this point in the code"之类的打印语句,然后以某种方式预先为NewStatement进行grep并将其发送到stdout,而其他一切都被视为正常。

本质上我想:

1)将包含stdout的{​​{1}}中的任何内容发送到NewStatement

2)将包含stdout的{​​{1}} 而非的任何内容发送至stdout

3)将NewStatement中的任何内容发送到out.out

这可能吗?

3 个答案:

答案 0 :(得分:1)

你可以这样做:

>out.out

./myCode.sh 2> err.err 1> >(awk '!/^NewStatement/{print > "out.out"; next} 1')
如果行不以awk开头,则进程替换中的

out.out命令将打印到NewStatement。否则,以NewStatement开头的行会打印到stdout

答案 1 :(得分:1)

或者,你可以

myCode.sh 2>err.err | tee >(grep -v NewStatement > out.out) | grep NewStatement

tee重复了stdin所有内容,所以

  • tee-ed流由grep -v patt过滤(例如,不包含)并重定向
  • stdout如果按grep patt过滤(例如,只有包含的行)

这可以随时重复,例如

cmd | tee >(cmd1) >(cmd2) >(cmd3) | cmd

答案 2 :(得分:0)

这很容易。首先,"初学者"溶液

创建一个wrapper脚本(或主脚本中的包装函数),其中包含以下内容:

#!/bin/bash

while read line || [[ $line ]]
do
  if
    [[ $line =~ NewStatement ]]
  then
    echo "$line"
  else
    echo "$line" >> out.out
  fi
done< <("$@" 2>err.err)

然后,只需像这样调用你的脚本(假设一切都是可执行的并且在当前目录中:

./wrapper myCode.sh

模式&#34;高级&#34;解决方案使用文件描述符打开目标文件进行写入。

#!/bin/bash

exec 3> out.out # Open file descriptor 3 for writing to file

while read line || [[ $line ]]
do
  if
    [[ $line =~ NewStatement ]]
  then
    echo "$line"
  else
    echo "$line" >> &3
  fi
done< <("$@" 2>err.err)

exec 3>&- # Close file descriptor

您可以使用许多文件描述符根据任意复杂条件对许多单独的文件执行输出。