【问题标题】:Using matched pattern in awk在 awk 中使用匹配模式
【发布时间】:2018-08-17 12:13:50
【问题描述】:

我想使用 awk 打印匹配的模式。不是场,不是线。

在 vi 中,您可以将匹配的模式放在替换中,方法是用括号括起来并用花括号和数字引用它,如下所示:

:s/bufid=([0-9]*)/buffer id is {\0}/

parens 之间匹配的部分被记住并可以使用。

在perl中也是类似

$_ = "Hello there, neighbor";
if (/\s(\w+),/) {             # memorize the word between space and comma
  print "the word was $1\n";  # the word was there
}

有什么方法可以用 awk 做类似的事情吗?我只想提取缓冲区 id 并打印它,只有它。

输入行是 XML,将包含(除其他外)'bufId="123456"'。我要打印“123456”

所以……

awk < file.xml '/bufId="([0-9]*)"/ { print X; }'

X 在哪里放什么?

这还能做到吗?

【问题讨论】:

  • 我发现最接近我想要的就是这个化合物:grep 'bufId="[0-9]*"' | sed 's/^.*bufId="//' | sed 's/([0-9]*)".*$/\1/'
  • 您可以只使用 XML 解析器并在一行中实现它!这也将提供更强大的解决方案,以防您有另一个属性 evilAttribute 包含像 bufld 这样的值,例如可能会欺骗 awksed

标签: regex awk


【解决方案1】:

gawk

awk '{print gensub(/.*bufId="([0-9]*)"/,"\\1",1)}'

如果你想引用结果,你也必须捕获引号。

【讨论】:

    【解决方案2】:

    这似乎与您所追求的非常接近。不确定awk 是否会成为您最好的工具。

    echo '<root><a bufId="123456"/></root>' | awk 'match($0, /bufId="/) { print substr($0, RSTART+7, RLENGTH-1)}'
    

    This 是一个有用的起点。

    【讨论】:

    • 这也需要gawk——值得一提,因为mawk至少是Ubuntu上的默认awk。
    • 你确定吗?适用于具有 BSD awk 而非 gnu awk 的 macOS。
    • 不,我错了,对不起。我相信你使用match 的方式不会。
    【解决方案3】:

    还有gawkmatch 中的第三个参数是特定的):

    ~/test£ cat test
    abc
    ~/test£ gawk '{ match($0, /a(.)(.)/, group)}{ print group[2] group[1]}' test
    cb
    

    【讨论】:

      【解决方案4】:

      我强烈建议您使用XML 解析器,而不是为此使用awk 解决方案:

      $ cat file.xml
      <elems><elem bufId="123456"/></elems>
      
      $ xmllint --xpath "concat('\"',string(//elem/@bufId),'\"')" file.xml
      "123456"
      
      $ xmllint --xpath "string(//elem/@bufId)" file.xml
      123456
      

      取决于您是否希望在输出中包含引号。

      另一个有效的解决方案是使用sed(如果你真的不喜欢XPATH 和XML 解析器,并且由于已经有很多好的awk 解决方案我也会介绍这个):

      $ sed -n 's/^.*bufId="\([0-9]*\)".*$/\1/gp' file.xml
      123456
      
      $ sed -n 's/^.*bufId="\([0-9]*\)".*$/"\1"/gp' file.xml
      "123456
      

      【讨论】:

      • 一个解析 XML 的 XML 解析器?你疯了吗!?
      • 谢谢你。我在上面提出了我自己的 grep/sed 解决方案,我希望有更简单的东西。我没有想到一个 xml 解析器。我可以在 perl 中做到这一点......但它不会是单线......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多