【问题标题】:Extract substring using sed使用 sed 提取子字符串
【发布时间】:2013-11-14 07:08:14
【问题描述】:

我有以下日志文​​件:

example.com - - - 127.0.01 [22/Sep/2013:07:22:22 +0000]  "POST /api/test.php HTTP/1.1" 200 355 "-" "-" "{\x22id\x22:\x22 ... }}}"

example.com - - - 127.0.01 [22/Sep/2013:07:22:22 +0000]  "POST /api/test.php HTTP/1.1" 200 355 "-" "-" "{\x22id\x22:"{\x22 ... }}}"

我想将第一个{\x22提取到最后一个}

所以我使用以下 sed 命令:

cat test.txt  | sed -r  's/.+?"(\{.+\})".*/\1/g'

但是,它给了我

{\x22id\x22:\x22 ... }}}

{\x22 ... }}}

但我想要

{\x22id\x22:\x22 ... }}}

{\x22id\x22:"{\x22 ... }}}

【问题讨论】:

    标签: regex linux sed


    【解决方案1】:

    .+? 不适用于 sed,因为它的正则表达式引擎不支持非贪婪匹配。

    但是如果你考虑 perl 是可能的:

    perl -pe 's/.+?"(\{.+\})".*/\1/g' test.txt
    {\x22id\x22:\x22 ... }}}
    {\x22id\x22:"{\x22 ... }}}
    

    或使用egrep -o

    egrep -o '\{.+\}' test.txt
    {\x22id\x22:\x22 ... }}}
    {\x22id\x22:"{\x22 ... }}}
    

    【讨论】:

    • 您也可以在激活 perl 引擎的情况下使用 grep。 grep -Ppgrep。该命令将是cat test.txt | grep -P -o "<regex pattern>"
    • @ffledgling:谢谢,更新的答案,是的egrep 也将与grep -P 一样工作
    • 区别 b/w egrepgrep -Egrep -P 是他们使用的正则表达式引擎。 egrepEREpgrep 是 Perl 的引擎。尽管我实际上从未见过太大的区别。 (注意 pgrep 和 grep -P 是不一样的,混淆了见谅)
    【解决方案2】:

    使用awk

    awk '{sub(/[^{]*{/,"{");sub(/}"/,"}")}1' file
    {\x22id\x22:\x22 ... }}}
    
    {\x22id\x22:"{\x22 ... }}}
    

    【讨论】:

      【解决方案3】:
      Cut="#CuT#"
      sed -n --posix "s/\({\\\\x22.*}\)\"$/${Cut}\1/;s/.*${Cut}//p" sample.txt
      

      我使用变量 Cut 来更改任何其他“标记”,具体取决于要处理的文本内容。变量本身不需要,如果您确定 Cut 的值不在文件中,您可以直接在 sed 中更改其内容

      【讨论】:

        【解决方案4】:

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

        sed 's/\({\\x22.*}\).*/\n\1/;s/.*\n//' file
        

        在第一场比赛中,贪婪是你的敌人,所以{\x22 使用分而治之的成语。即放置一个唯一标记(在本例中为 \n)并使用第二个替换命令删除字符串的第一部分。最后一个} greed 是你的朋友,因为.*} 会自己找到最后一个匹配项。

        注意如果第一个匹配是单个字符,比如X,那么否定字符类[^X]* 就足够了。但是,由于它是一个字符串(两个或更多字符),所以这不起作用。

        【讨论】:

          猜你喜欢
          • 2017-01-31
          • 2013-05-16
          • 2016-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-11
          相关资源
          最近更新 更多