【问题标题】:sed repetition match misbehavingsed 重复匹配行为不端
【发布时间】:2021-01-25 03:35:49
【问题描述】:

我正在尝试从以下字符串获取文件路径:

"# configuration file /etc/nginx/conf.d/default.conf"

将其传递给sed:

sed -n 's,\(# configuration file \)\(\/[a-zA-Z_.]\+\)\+,\1,'

我希望/etc/nginx/conf.d/default.conf\1 捕获,但令人惊讶的是 仅返回 default.conf 部分。在这里,我了解所引用的 每次下一个匹配 /[a-zA-Z_.]\+ 时都会重新填充部分。这不是合乎逻辑吗 每个下一个匹配项都转到下一个引用,所以default.conf 将在\4 中返回?

/[a-zA-Z_.]\+ >>>

\(/etc\)\(/nginx\)\(/conf.d\)\(/default.conf\)
   \1        \2        \3           \4

【问题讨论】:

  • " 都是字符串的一部分吗?
  • 您在字符类中缺少/。您可以使用:sed -E 's~# configuration file +(/[a-zA-Z/_.]+)+~\1~'
  • 你需要第二次捕获:echo "# configuration file /etc/nginx/conf.d/default.conf" | sed -e 's,\(# configuration file \)\(\/[a-zA-Z_./]\+\)\+,\2,' 返回/etc/nginx/conf.d/default.conf
  • @Cyrus, no " 不是字符串的一部分
  • @l00p:与awkecho "# configuration file /etc/nginx/conf.d/default.conf" | awk '{print $NF}'$NF 包含最后一列的内容。

标签: regex sed pattern-matching


【解决方案1】:

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

sed -nE 's,(# configuration file )((/[a-zA-Z_.]+)+),\2,p' file

这将捕获文件路径。

sed -nE 's,(# configuration file )((/[a-zA-Z_.]+)+),\1,p' file

这将捕获评论的开头。

sed -nE 's/(# configuration file )((\/[a-zA-Z_.]+)+)/\3/p' file

这将捕获文件路径的结尾。

注意当捕获组被可能重复的东西限定时,即*?+{...} 之间的任何东西,它将保留最后一次这样的重复(参见解决方案 3)。

【讨论】:

  • @EdMorton 谢谢。我将修改一个解决方案以使用 / 作为分隔符,以突出显示其最初被转义/引用的原因。
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 2023-03-13
  • 1970-01-01
  • 2015-05-12
相关资源
最近更新 更多