【问题标题】:awk space between two words regex两个单词正则表达式之间的 awk 空格
【发布时间】:2021-01-06 12:49:17
【问题描述】:

我的文本文件看起来像

abc d="cde"
abc d="cde"
abc d="cde"
abc d="cde"
something abc d="cde"
something abc d="cde"
d="123"
d="123"

我与awk 有一个循环

awk '{for(i=1;i<=NF;i++){if($i~/d=/){sub(/d=".*"/,"d=\""++count"\"",$i)}}} 1;' inputFile

它给了

abc d="1"
abc d="2"
abc d="3"
abc d="4"
something abc d="5"
something abc d="6"
d="7"
d="8"

但我只想更改abc d=。所以我将代码更新为

awk '{for(i=1;i<=NF;i++){if($i~/abc d=/){sub(/abc d=".*"/,"abc d=\""++count"\"",$i)}}} 1;'

awk '{for(i=1;i<=NF;i++){if($i~/abc[[:space:]]d=/){sub(/abc[[:space:]]d=".*"/,"abc d=\""++count"\"",$i)}}} 1;'

以上都不起作用。我期望的输出是

abc d="1"
abc d="2"
abc d="3"
abc d="4"
something abc d="5"
something abc d="6"
d="123"
d="123"

所以问题是如何正确包含spaceabc[[:space:]]dabc dabc[[:blank:]]d?我累了他们所有人,但没有工作。

【问题讨论】:

  • 如果你测试你的最后两次尝试,你会看到没有任何东西被替换,这是因为没有字段匹配该模式。一个字段是abc,另一个是d=,但不存在abc d= 字段。请参阅下面的答案了解如何在此处使用sub
  • 如果abc d=之前没有双引号,那么只需awk 'BEGIN{FS=OFS="\""}$1~/abc d=$/{$2=++n}1' file
  • @jxc 在这个问题中,abcd= 可以存在于各种字段位置,例如1和2,或者2和3,最好不要拆分到字段。
  • 与你的样本数据,当你使用"作为FS来分割行时,如果abc d=之前没有任何其他",则该数字将始终位于$2abc d=$1 的末尾?
  • @jxc 好主意,但$1~/abc 也匹配应该排除的情况,例如abc some text d="x"。加上你提到的,关于可能在以前的职位上的"。最好单独使用sub,不要拆分字段,因为问题要求匹配abc d=

标签: regex awk


【解决方案1】:
  • 拆分到字段并处理字段
  • 或者不要拆分并测试整行的替换模式。

你问题的问题不是使用什么模式,两者都很好,但是你在字段上使用它们,而你应该在整行上使用它们。

第一种解决方案 - 子(模式,替换)

根据你的描述推荐这个(sub适用于默认$0)。

awk '{sub(/abc d=.+$/,"abc d=\""++count"\"")}1' file

第二个解决方案 - 拆分为字段

awk '$(NF-1)~/abc$/ && $NF~/^d=/{$NF="d=\""++count"\""}1' file

请注意,此处接受字段之间的更多空格。

【讨论】:

  • 感谢您的回答!似乎没有循环工作awk '{for(i=1;i&lt;=NF;i++){if($i~/abc d=.+$/){sub(/abc d=.+$/,"abc d=\""++count"\"",$i)}}} 1;'
  • 我的回答是,如果你想使用sub,你应该循环。一般来说,绝对没有理由为此任务循环遍历所有字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 2020-06-09
  • 2016-08-25
  • 2013-03-06
相关资源
最近更新 更多