sed 在捕获组中表现不正常;看不出有什么问题

sed not behaving properly w/ capture group; can't see what's wrong

抱歉不得不 post 这看起来很基本,但我不知道为什么它不起作用:

sed -r -i.bak 's/-- Database: (.*?)\n/CREATE DATABASE \n/g' file.sql

该文件包含如下所示的一行:

-- Database: `omptest`

并在 sublime 中做与 find/replace 完全相同的事情:

Find: -- Database: (.*?)\n
Replace with: CREATE DATABASE \n

sed 似乎不喜欢 \1 除非我转义捕获组周围的括号或使用 -r 扩展正则表达式——否则它会抛出 sed: -e 表达式 #1, char 53: 无效引用\1 在 `s' 命令的 RHS 上。

无论如何,当我使用 -r 或转义括号时,它不会编辑文件,就好像它没有起作用一样。我不知道为什么。

我想我要么忘记了,要么刚刚发现了一些奇怪的 sed 正则表达式 属性,但我终究无法弄清楚可能是什么问题。感谢帮助!

sed 在基于行的基础上工作并且在文件中看不到换行符(除非你做了特殊的事情)。使用

#                                 vvv----------------vvv--- no newlines
sed -r -i.bak 's/-- Database: (.*?)/CREATE DATABASE /g' file.sql

附录: 还有三点要注意,也许:

  1. .*? 与 sed 中的 .* 完全相同。前者可以用于其他一些正则表达式引擎中的非贪婪匹配,但不能用于 sed。 ? 没有任何危害,但它也没有任何作用。
  2. 由于正则表达式贪婪地匹配到行尾,/g 标志没有任何影响。永远不会有第二场比赛,因为第一场比赛延伸到行尾。
  3. 由于捕获组已放回找到它的位置,因此实际上并不需要一开始就捕获它。

根据前两个观察,我们可能会得出原始脚本的简化版本:

sed -r -i.bak 's/-- Database: (.*)/CREATE DATABASE /' file.sql

...并且由于第三个,我们可以再次放弃这些更改并仅使用

sed -i.bak 's/-- Database: /CREATE DATABASE /' file.sql

相反。