【问题标题】:Sed Regex ^.* (caret dot asterisk) doesn't match correctlySed 正则表达式 ^.*(插入点星号)不正确匹配
【发布时间】:2016-01-23 09:09:56
【问题描述】:

目前我有一个格式如下的文件:

####<Oct 23, 2015 10:23:34 AM PDT> <ERROR> <com.foo.biz.jrules.ilog.RulesEngine> <BELC02NF206G3QN> <tcbiz2_1> <siteType=DOMESTIC> <catalina-exec-16> <sessionId=432407E73A6BFE1C4AFE8205ED386907> <clientIp=127.0.0.1> <com.foo.biz.jrules.ilog.RulesEngine.mapPricedSearch(?:?):priceRuleDesc=SNSDTA:PRO-18.612782:NOBTA>
####<Oct 23, 2015 10:23:34 AM PDT> <ERROR> <com.foo.biz.jrules.ilog.RulesEngine> <BELC02NF206G3QN> <tcbiz2_1> <siteType=DOMESTIC> <catalina-exec-16> <sessionId=432407E73A6BFE1C4AFE8205ED386907> <clientIp=127.0.0.1> <com.foo.biz.jrules.ilog.RulesEngine.mapPricedSearch(?:?):priceRuleDesc=SNSDTA:PRO-15.806297:NOBTA>
####<Oct 23, 2015 10:23:34 AM PDT> <ERROR> <com.foo.biz.jrules.ilog.RulesEngine> <BELC02NF206G3QN> <tcbiz2_1> <siteType=DOMESTIC> <catalina-exec-16> <sessionId=432407E73A6BFE1C4AFE8205ED386907> <clientIp=127.0.0.1> <com.foo.biz.jrules.ilog.RulesEngine.mapPricedSearch(?:?):priceRuleDesc=SNSDTA:PRO-4.2497005:NOBTA>

我正在尝试删除 priceRuleDesc= 术语之后和最后一个 &gt; 字符之前的所有内容。目前,我正在尝试在我的 Mac 上测试 sed 中的正则表达式来完成此操作,但运气不佳。

我使用的命令是:

cat ~/myapp/logs/tcbiz2_1.log | grep -i priceRuleDesc | sed -E 's/^.*priceRuleDesc=/foo/'

令人惊讶的是,在我的 sed 命令中,^.*priceRuleDesc= 并不能匹配到用 foo 替换之前的所有内容。我怀疑^.* 只是走到队伍的尽头,而没有足够聪明地在priceRuleDesc 发生时停下来。我发现了另一个与 Non greedy regex matching in Sed 有点相似的问题,但我不相信这个问题中发生的事情就是这里发生的事情,我也想知道是否有 Sed 解决方案。另外,我确信这一定是我没有找到的其他问题的重复。因此,如果有人能指出我正确的问题,那将是很好的,或者提供一个很好的答案。谢谢。

【问题讨论】:

  • 你不需要grep 在这里你的sed 只会修改已经匹配的行。 (如果您确实需要过滤,您也可以直接在 sed 中执行此操作。sed -E '/priceRuleDesc/s/..../.../'
  • 正确,但我需要 grep 来过滤掉没有 priceRuleDesc 的行。我忽略了将其添加到示例文件中。
  • 不。只需使用格式化的sed -nE '/priceRuleDesc=/{ s/..../..../;p }',但是您的sed 需要那个大括号。

标签: regex macos sed


【解决方案1】:

所以我终于弄清楚发生了什么。我想我会发布这个答案,以防其他人遇到同样的问题。本质上,该问题与 sed 命令的正则表达式中的 .* 术语完全无关。一切都与grep有关。问题是 grep 突出显示了匹配的 priceRuleDesc= 术语并且没有考虑到这一点。我的 grep 命令突出显示了术语,因为嵌入在大 ~/.bash_profile 中我已经放置了命令(从其他人的工作文件中的一堆东西中复制并批量粘贴):

export GREP_OPTIONS='--color=auto'

此选项的效果是,当 grep 现在匹配文本时,它实际上通过插入您在该标准输出中看不到的字符来对其进行转换。虽然在美学上更令人愉悦,但不幸的是,这会使输出对其他使用 grep 输出管道的正则表达式(即 sed 命令)的命令无用。但是,您可以通过xxd 命令查看这些字符。

0015960: 3f29 3a1b 5b30 313b 3331 6d1b 5b4b 7072  ?):.[01;31m.[Kpr
0015970: 6963 6552 756c 6544 6573 631b 5b6d 1b5b  iceRuleDesc.[m.[
0015980: 4b3d 3e0a                                K=>.

您可以在此处看到最后一个 c 字符和最后一个 = 字符之间有六个字符的问题,它们负责创建突出显示效果。通过注释掉我的~/.bash_profile 中的GREP_OPTIONS 行并重新启动终端,grep 命令最终没有添加与发布的正则表达式不匹配的无关字符。

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -E '/.*priceRuleDesc=(.*)>$/s//\1/p;d' file
    

    这也可以代替 grep 命令。

    【讨论】:

      【解决方案3】:

      您可以只使用基于否定的正则表达式:

      sed 's/^.*priceRuleDesc=\|>$//g' file
      SNSDTA:PRO-18.612782:NOBTA
      SNSDTA:PRO-15.806297:NOBTA
      SNSDTA:PRO-4.2497005:NOBTA
      

      或者使用awk:

      awk -F 'priceRuleDesc=|>$' '{print $2}' file
      SNSDTA:PRO-18.612782:NOBTA
      SNSDTA:PRO-15.806297:NOBTA
      SNSDTA:PRO-4.2497005:NOBTA
      

      【讨论】:

      • 但问题是我不想替换 priceRuleDesc 之后的任何内容,只替换它之前的内容。
      • 但是您写道:我正在尝试删除 priceRuleDesc= 术语之后和最后一个 > 字符之前的所有内容。对于显示的输入,您的预期输出是什么?
      • 完全混乱的语言。我的错。我的意思是我只想保留 priceRuleDesc 之后的数据。很抱歉造成混乱。
      • 所以你希望SNSDTA:PRO-18.612782:NOBTA&gt; 在第一行作为输出?
      • 感谢 anubhava,如果没有我没有考虑到的突出显示的字符,您的回答肯定会奏效。有关详细信息,请参阅下面的答案。感谢您的帮助 - 非常感谢,并且在排除故障以找出发生的情况时绝对有用。
      【解决方案4】:

      对我来说很好用:

      mike ~ $ cat foo.txt
      ####<Oct 23, 2015 10:23:34 AM PDT> <ERROR> <com.foo.biz.jrules.ilog.RulesEngine> <BELC02NF206G3QN> <tcbiz2_1> <siteType=DOMESTIC> <catalina-exec-16> <sessionId=432407E73A6BFE1C4AFE8205ED386907> <clientIp=127.0.0.1> <com.foo.biz.jrules.ilog.RulesEngine.mapPricedSearch(?:?):priceRuleDesc=SNSDTA:PRO-18.612782:NOBTA>
      ####<Oct 23, 2015 10:23:34 AM PDT> <ERROR> <com.foo.biz.jrules.ilog.RulesEngine> <BELC02NF206G3QN> <tcbiz2_1> <siteType=DOMESTIC> <catalina-exec-16> <sessionId=432407E73A6BFE1C4AFE8205ED386907> <clientIp=127.0.0.1> <com.foo.biz.jrules.ilog.RulesEngine.mapPricedSearch(?:?):priceRuleDesc=SNSDTA:PRO-15.806297:NOBTA>
      ####<Oct 23, 2015 10:23:34 AM PDT> <ERROR> <com.foo.biz.jrules.ilog.RulesEngine> <BELC02NF206G3QN> <tcbiz2_1> <siteType=DOMESTIC> <catalina-exec-16> <sessionId=432407E73A6BFE1C4AFE8205ED386907> <clientIp=127.0.0.1> <com.foo.biz.jrules.ilog.RulesEngine.mapPricedSearch(?:?):priceRuleDesc=SNSDTA:PRO-4.2497005:NOBTA>
      mike ~ $ sed -E 's/^.*priceRuleDesc=/foo/' foo.txt 
      fooSNSDTA:PRO-18.612782:NOBTA>
      fooSNSDTA:PRO-15.806297:NOBTA>
      fooSNSDTA:PRO-4.2497005:NOBTA>
      mike ~ $ 
      

      我建议先检查 sed 的输入

      【讨论】:

      • 迈克,你用的是 Mac 吗?
      • 是的,内置 sed 的 El Capitan
      猜你喜欢
      • 1970-01-01
      • 2018-12-30
      • 2014-09-06
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-03
      相关资源
      最近更新 更多