使用tee和while循环进行Bash进程替换

时间:2019-01-06 16:45:39

标签: bash tee process-substitution

我想在while循环中使用带有tee的嵌套进程替换。

while read line; do
  #process line
  echo "--$line"
done < <(cat sample.file | tee >(grep "SPECLINE") | grep "LINESTOPROCESS")

因此,我需要:

  • sample.file中包含“ LINETOPROCESS”表达式的所有行都应传递到循环中,并以“-”前缀打印。
  • 所有包含“ SPECLINE”的行都需要在tee的第一个过程替换中(在grep中)打印。

我想避免将sample.file太大而太重。

带有一个简单的sample.test文件:

line1 SPECLINE
line2 LINETOPROCESS
line3 LINETOPROCESS
line4 SPECLINE
line5 I don't need it
line6 also not
line7 also not
line8 SPECLINE
line9 LINETOPROCESS

我的结果:

# ./test.sh
#

我想要的结果:

# ./test.sh
line1 SPECLINE 
--line2 LINETOPROCESS
--line3 LINETOPROCESS
line4 SPECLINE
line8 SPECLINE
--line9 LINETOPROCESS

或者我也可以接受它作为输出:

# ./test.sh
--line2 LINETOPROCESS
--line3 LINETOPROCESS
--line9 LINETOPROCESS
line1 SPECLINE 
line4 SPECLINE
line8 SPECLINE

UPDATE1

gres仅用于演示。 我真的需要那两个替换。

  • sample.file是一个http文件。
  • grep“ SPECLINE”应为“ hxselect -i -s';” -c'div.hour'
  • grep“ LINESTOPROCESS”为“ hxselect -i -s';” -c'div.otherclass'| hxpipe

hx程序不是面向行的。他们正在从stdin读取并输出到stdout。

因此,tee的第一个命令将选择具有“ hour”类的div,并以“;”将其分开。然后,Tee之后的管道将选择所有具有“ otherclass”类的div,hxpipe会将其展平以进行循环以供进一步处理。

3 个答案:

答案 0 :(得分:3)

我根本不会使用任何进程替代。

while IFS= read -r line; do
  if [[ $line = *SPECLINE* ]]; then
    printf '%s\n' "$line"
  elif [[ $line = *LINETOPROCESS* ]]; then
    printf '--%s\n' "$line"
  fi
done < sample.txt

您已经付出了在bash中逐行读取输入流的费用;没有理由增加两个单独的grep进程的开销。

一个单独的awk处理会更好,因为它比bash一次读取一个字符的方法读取文本行的效率更高。

awk '/SPECLINE/ {print} /LINETOPROCESS/ {print "--"$0}' sample.txt

(如果单行可以同时匹配SPECLINELINETOPROCESS,这太简单了,但我将其留给读者修正)。

>

答案 1 :(得分:0)

以下内容仅循环遍历整个文件,仅打印匹配的行。其他所有行均被忽略。

while read line; do
    case "$line" in
        *SPECLINE*) echo "$line" ;;
        *LINETOPROCESS*) echo "--$line" ;;
    esac
done < sample.file

答案 2 :(得分:0)

当您需要tee时,可以进行2次更改。
您的测试代码进入LINE S TOPROCESS,输入是LINETO ..
输出过程替换会产生类似https://stackoverflow.com/a/42766913/3220113的问题。您可以采取其他方式。

while IFS= read -r line; do
  #process line
  echo "--$line"
done < x2 |
tee >(grep "SPECLINE") >(grep "LINETOPROCESS") >/dev/null

我不知道hxselect,但是它似乎可以在完整的格式正确的XML文档上运行,因此请避免使用grep