【问题标题】:awk gsub regex expression, match word not in double quotesawk gsub 正则表达式,匹配单词不在双引号中
【发布时间】:2021-08-22 03:53:25
【问题描述】:

我编写了一个正则表达式来尝试使用 gsub 和 awk 替换每次出现的不在双引号中的单词。然而,即使该表达式适用于在线计算器,该表达式也不会替换我脚本中的任何内容。

输入 =

studentNum=="00000"{print name, "is the prof"}

表达式:

gsub( "studentNum(?=[^"]*(?:"[^"]*"[^"]*)*$)", "XXX", input)

预期输出:

XXX=="00000"{print name, "is the prof"}

【问题讨论】:

  • 您的正则表达式似乎试图替换双引号中的单词之前的单词,而不是每次出现的单词都不是双引号。如果您想替换不是在双引号中出现的每个单词,您应该在示例输入/输出中的双引号中包含该单词的示例。

标签: regex unix awk


【解决方案1】:

使用match 功能:awk 不支持前瞻机制,请使用您显示的示例尝试以下操作。

awk '
match($0,/^studentNum=="[0-9]+"{.*}$/){
  val=substr($0,RSTART,RLENGTH)
  sub(/^[^"]*/,"XXX==",val)
  print val
}
'  Input_file

没有match函数:

awk '
/^studentNum=="[0-9]+"{.*}$/{
  sub(/^[^"]*/,"XXX==")
}
1
'  Input_file

解释: 简单的解释是:在这里使用awkmatch 函数来匹配studentNum=="digits"{ 直到行尾。然后用匹配值中的XXX== 替换从开始到第一次出现" 的所有内容,然后打印匹配值。

奖励解决方案(匹配):如果您有不匹配条件的行,并且您想打印匹配条件和不匹配的两行然后尝试以下:

awk '
match($0,/^studentNum=="[0-9]+"{.*}$/){
  val=substr($0,RSTART,RLENGTH)
  sub(/^[^"]*/,"XXX==",val)
  $0=val
}
1
'  Input_file

【讨论】:

    【解决方案2】:

    在线正则表达式验证器只能证明您的正则表达式可以与特定的在线正则表达式验证器一起使用,它不能证明它可以与任何给定的命令行工具一起使用。特别是您的正则表达式是 PCRE,而 sed 默认支持 BRE,而 awk 支持 ERE。没有支持 PCRE 的强制性 POSIX 工具。

    这是你想要做的吗?

    $ sed 's/studentNum\(=="[^"]*"\)/XXX\1/' file
    XXX=="00000"{print name, "is the prof"}
    
    $ awk '{print gensub(/studentNum(=="[^"]*")/,"XXX\\1",1)}' file
    XXX=="00000"{print name, "is the prof"}
    

    sed 脚本可以在任何 sed 中工作,awk 脚本需要一个具有 gensub() 的 awk,例如GNU awk。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 2016-12-13
      相关资源
      最近更新 更多