代码之家  ›  专栏  ›  技术社区  ›  User1

如何阻止SED缓冲?

  •  7
  • User1  · 技术社区  · 15 年前

    我有一个写入FD3的程序,我想用grep和sed处理这些数据。以下是迄今为止代码的外观:

    
    exec 3> >(grep "good:"|sed -u "s/.*:\(.*\)/I got: \1/")
    echo "bad:data1">&3
    echo "good:data2">&3
    

    在我执行

    exec 3>&-

    然后,我想要的一切最终如我所料到达:

    I got: data2
    

    如果我只使用grep或sed,它似乎会立即回复,但是混合它们似乎会导致某种缓冲。如何从FD3获得即时输出?

    4 回复  |  直到 10 年前
        1
  •  4
  •   tchrist    15 年前

    另一种停止的方法 sed 从缓冲开始就是运行它 the s2p sed-to-Perl translator 并插入一个指令来缓冲它的命令,可能类似于

    BEGIN { $| = 1 }
    

    这样做的另一个原因是它为您提供了来自ERES的更方便的符号,而不是令人讨厌的反斜杠遗留BRES。您还可以得到完整的Unicode属性,这通常是非常关键的。

    但是你不需要翻译就可以这么简单 塞德 命令。你不需要两者 grep 塞德 或者。所有这些工作:

    perl -nle 'BEGIN{$|=1} if (/good:/) { s/.*:(.*)/I got: $1/; print }'
    
    perl -nle 'BEGIN{$|=1} next unless /good:/; s/.*:(.*)/I got: $1/; print'
    
    perl -nle 'BEGIN{$|=1} next unless /good:/; s/.*:/I got: /; print'
    

    现在您也可以访问最小量词, *? , +? , ?? , {N,}? {N,M}? . 这些现在允许像 .*? \S+? [\p{Pd}.]?? 可能更可取。

        2
  •  8
  •   User1    15 年前

    我想我找到了。出于某种原因,grep不会自动进行行缓冲。我添加了一个 --line-buffered 选择 grep 现在它立即做出反应。

        3
  •  3
  •   zwol    15 年前

    您可以合并 grep 进入 sed 就像这样:

    exec 3> >(sed -une '/^good:/s//I got: /p')
    echo "bad:data1">&3
    echo "good:data2">&3
    

    稍微解包一下:您可以将regexp(像往常一样放在斜杠之间)放在任何sed命令之前,这使得它只应用于与该regexp匹配的行。如果第一个regexp参数 s 命令是空字符串( s//whatever/ )然后它将重用最后一个匹配的regexp,在本例中是前缀,这样就省去了必须重复的操作。最后, -n 选项告诉SED只打印指定要打印的内容,并且 /p 上的后缀 S 命令告诉它打印替换的结果。

    这个 -e 选项不是严格必需的,但它是良好的样式,它只是表示“下一个参数是SED脚本,而不是文件名”。

    除非需要在其中替换shell变量,否则始终将sed脚本放在单引号中,即使这样,我也会将所有内容都放在 但是 单引号中的shell变量(当然,shell变量是双引号)。这样你就避免了一堆与反斜杠相关的悲伤。

        4
  •  2
  •   Alice Purcell    10 年前

    在Mac电脑上, brew install coreutils 并使用gstdbuf控制grep和sed的缓冲。