【问题标题】:Sed extract 2nd wordsed 提取第二个单词
【发布时间】:2011-10-11 10:28:49
【问题描述】:

我想知道为什么我这样做时它不起作用:

echo "d_suites/k_val/tests/asm/logs/kf_on_stage1 FAILED 0:00:22 Jul 22 22:33 " | 
    sed 's/[ \t]*\([^ \t]+\)[ \t]+\([^ \t]+\).*/\2/'

但是这个(将 + 更改为 * )有效:

echo "d_suites/k_val/tests/asm/logs/kf_on_stage1 FAILED 0:00:22 Jul 22 22:33 " |
     sed 's/[ \t]*\([^ \t]*\)[ \t]*\([^ \t]*\).*/\2/'

任何帮助将不胜感激。

【问题讨论】:

    标签: regex sed terminal


    【解决方案1】:

    Sed 默认不支持+ 通配符。

    $ echo "aaabbbccc" | sed "s/a+/XXX/g"
    aaabbbccc
    

    您可以使用 -r 标志 (on GNU sed) 或 -E 标志(在 Mac OS X 上,我怀疑是 *BSD sed)启用它,因为这些选项允许使用扩展正则表达式(相反到基本的正则表达式):

    $ echo "aaabbbccc" | sed -E "s/a+/XXX/g"
    XXXbbbccc
    

    如果你使用 GNU sed,它 supports+ 在基本正则表达式模式下作为转发器,如果​​你用反斜杠转义它:

    $ echo "aaabbbccc" | sed "s/a\+/XXX/g"
    

    【讨论】:

      【解决方案2】:

      第一个不起作用,因为您需要转义您的 +,如下所示:

      echo "d_suites/k_val/tests/asm/logs/kf_on_stage1 FAILED 0:00:22 Jul 22 22:33 " | 
          sed 's/[ \t]*\([^ \t]\+\)[ \t]\+\([^ \t]\+\).*/\2/'
      

      编辑

      有关原因的更多信息,请阅读this very informative comment

      【讨论】:

      • 谢谢,它现在可以工作了,但我不得不说,区别对待 + 和 * 很难理解。
      • 添加 -E 标志并删除这些转义将使您的正则表达式更具可读性。
      • 我试过 sed -E -e ,它没有用,但无论如何,这是一个信息丰富的评论。
      【解决方案3】:

      如果你没有完全嫁给 sed,awk 会更易读:

      echo "..." | awk '{print $2}'
      

      【讨论】:

        【解决方案4】:

        已编辑 - 现在指的是[^ \t]

        [^ \t]+ 是 1-n 个标签,要求有一个非标签。
        [^ \t]* 是 0-n 个标签,不需要成为非标签。

        没有在你的输入字符串中有一个非制表符

        【讨论】:

        • 我知道+和*的区别,但是([^ \t]*)和([^ \t]+)是我看不懂的。
        • [^ \t] 表示任何不是空格或制表符的东西。
        • [^\t] 是任何非制表符。所以[^\t]+ 是 1-n 个非标签,而 [^\t]* 是 0-n 个非标签。方便吧?
        • 糟糕。我更改了答案以反映您的 cmets。不过,答案或多或少还是一样的——+ 需要匹配
        • ([^ \t]*) VS ([^ \t]+),请尝试我的命令,为什么 ([^ \t]+) 无法提取第二个单词。我确实知道 [^ \t] 是什么意思...
        猜你喜欢
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        • 2016-05-23
        • 2011-12-13
        • 1970-01-01
        • 2023-03-23
        相关资源
        最近更新 更多