Perl 从bash分离的流是否可以转置到其他语言?

Perl 从bash分离的流是否可以转置到其他语言?,perl,python,ruby,c++,stream-processing,Perl,Python,Ruby,C++,Stream Processing,流拆分是指能够: 通过第一个函数动态过滤流内容 流的一部分由第二个函数处理 流的其余部分由第三个函数处理 流从未被存储(在运行中) 一个例子有时比一个冗长的解释要好。此命令行使用和分割流: $> cut -f2 file | tee >( grep "AB" | sort | ... ) | grep -v "AB" | tr A B | ... 在本例中,流被拆分为两行:包含“AB”的行和其余的行: cut -f2 file ---->- line contains "AB

流拆分是指能够:

  • 通过第一个函数动态过滤流内容
  • 流的一部分由第二个函数处理
  • 流的其余部分由第三个函数处理
  • 流从未被存储(在运行中)
  • 一个例子有时比一个冗长的解释要好。此命令行使用和分割流:

    $> cut -f2 file | tee >( grep "AB" | sort | ... ) | grep -v "AB" | tr A B | ...
    
    在本例中,流被拆分为两行:包含
    “AB”
    的行和其余的行:

    cut -f2 file ---->- line contains "AB" ->- sort ->- ...
                 \--->- does not contain "AB" ->- tr A B ->- ...
    
    但是我不喜欢这种流分割技术,因为流首先被复制(通过
    tee
    ),然后被过滤两次(通过
    grep
    grep-v

    因此,我想知道在其他语言中是否有类似流拆分的功能,如

    下面我提供一个更复杂的例子


    复杂的
    bash
    流分割
    counter.sh
    将流分成三部分(开始、中间和结束)。对于每个部分,再次分割流以统计符号的出现次数


    结论:流拆分在
    python
    /
    perl
    /
    awk
    /
    C++
    中比使用++做得更好。

    Tee只是一个使用基本系统调用的C程序,您可以用提供对系统库访问的任何语言实现它

    谷歌搜索

    用我最喜欢的语言


    应该能找到你需要的所有答案

    你提到的任何一种语言都非常适合这种情况


    在Perl中,我不会使用diff命令,我只会在原始文件上使用。

    如果要在Python中将相同的数据馈送到多个进程或线程中,则需要获取数据,然后将数据馈送到要馈送的进程。现在有了“你将如何实现这一点”;这个问题根本没有意义。问题中也没有性能问题。@olibre:没有,
    shell
    会这样做,正如您在上面演示的那样。我怀疑你想得太多了。试着用一个具体的问题来问一个具体的问题,我想这个问题会澄清的。“流永远不会存储在一个临时缓冲区中”-这个要求毫无意义。流数据将被复制到变量中。你无法避免。该变量是一个临时缓冲区。在C++中,你可以使用它将任何输入迭代器转换成前向迭代器。创建一个函数,逐行读取流。2.对于应由一个函数处理的行,将数据发送到该函数。3.对于应该由另一个函数处理的行,将数据发送到该函数。就像我说的,你想得太多了。你获取数据,然后处理它。好了,嗨,弗雷德。你是指例如这个还是这个?我没有意识到这些可能性。我不是在寻找这样的信息,但谢谢你的提示+1。我已经修改了我的问题。希望你喜欢这个重新措辞的版本。干杯;)也许还有另一个答案,但我在问题中给出的答案是我现在的想法。要在bash中分割流,您必须复制流(
    tee
    ),并对每个流进行两次过滤(例如:
    grep-pattern
    grep-v-pattern
    )。(我在另一个注释中继续我的解释)在Python(或其他语言)中,您可以一行接一行地处理流,并且对于每一行,决定使用不同的函数/线程/进程来处理它。此操作符合我在问题开头所述的流拆分定义。但当我问这个问题时,我没有想到这一点。我看到了你的回答,也看到了@LennartRegebro的评论,这让我大开眼界。(也许这不是你在写答案时所想的…)我不擅长Perl或Python,但这些语言中可能有流操作功能,可以简化流拆分的编写。。。如果这是真的,这可能是我问题的另一个答案。无论如何,你是唯一一个说“任何一种语言[…]都非常适合这个”=>因此你得到了正确的答案!干杯谢谢@ysth我将更新问题的答案,使其更清楚。(我把上面的评论作为灵感……)干杯:)
    #!/bin/bash    
    {
      {  tee >( sed -n '1,/^--$/!p' >&3 ) |
                sed -n '1,/^--$/p'        |
         tee >( echo "del at begin:  $(grep -c '<')"    >&4 ) |
         tee >( echo "add at begin:  $(grep -c '>')"    >&4 ) |
              { echo "chg at begin:  $(grep -c '|')"; } >&4
      }  3>&1 1>&2  |
      {  tee >( sed -n '/^--$/,/^--$/!p' >&3 ) |
                sed -n '/^--$/,/^--$/p'        |
         tee >( echo "del at end:    $(grep -c '<')"    >&4 ) |
         tee >( echo "add at end:    $(grep -c '>')"    >&4 ) |
              { echo "chg at end:    $(grep -c '|')"; } >&4
      }  3>&1 1>&2 |
         tee >( echo "del in middle: $(grep -c '<')"    >&4 ) |
         tee >( echo "add in middle: $(grep -c '>')"    >&4 ) |
                echo "chg in middle: $(grep -c '|')"; 
    } 4>&1
    
    $> cat file-A
    1
    22
    3
    4
    5
    6
    77
    8
    
    $> cat file-B
    22
    3
    4
    42
    6
    77
    8
    99
    
    $> diff --side-by-side file-A file-B | egrep -1 '<|\||>' | ./counter.sh
    del at begin:  1
    add at begin:  0
    chg at begin:  0
    del at end:    0
    add at end:    1
    chg at end:    0
    del in middle: 0
    add in middle: 0
    chg in middle: 1
    
    while input-stream
    {
        case (begin section)
        {
            case (symbol <) aB++ 
            case (symbol |) cB++ 
            case (symbol >) dB++
        }
        case (middle section)
        {
            case (symbol <) aM++ 
            case (symbol |) cM++ 
            case (symbol >) dM++
        } 
        case (ending section)
        {
            case (symbol <) aE++ 
            case (symbol |) cE++ 
            case (symbol >) dE++
        }
    }
    
    PrintResult (aB, cB, dB, aM, cM, dM, aE, cE, dE)