在sed命令中使用占位符/变量

11
我想将匹配结果的特定部分存储为变量以便稍后替换使用。我希望这能够在一行代码中完成而不是事先查找需要的变量。 在配置Apache并使用mod_rewrite时,您可以指定要用作变量的模式的特定部分,如下所示:
RewriteRule ^www.example.com/page/(.*)$ http://www.example.com/page.php?page=$1 [R=301,L]

在匹配模式中,括号内的部分被保存为 $1 以供后续使用。因此,如果URL是www.example.com/page/home,则它将被替换为www.example.com/page.php?page=home。因为括号内部分是模式中的一部分,所以匹配的“home”部分被保存在 $1 中。

我希望能够使用 sed 命令实现类似的功能,我需要自动替换 SQL 转储文件中的许多字符串,在每个创建表之前添加 "drop table if exists" 命令,但我需要知道表名才能执行此操作。因此,如果转储文件包含以下内容:

...
CREATE TABLE `orders`
...

我需要运行类似以下的内容:

cat dump.sql | sed "s/CREATE TABLE `(.*)`/DROP TABLE IF EXISTS $1\N CREATE TABLE `$1`/g"

获取以下结果的方法:

...
DROP TABLE IF EXISTS `orders`
CREATE TABLE `orders`
...

我正在使用sed命令中的mod_rewrite语法作为我的逻辑示例,展示我想要做的事情。

有任何建议吗?

4个回答

13
sed '/CREATE TABLE \([^ ]*\)/ s//DROP TABLE IF EXISTS \1; &/'

找到一个CREATE TABLE语句并捕获表名。将其替换为'DROP TABLE IF EXISTS'和表名,加上分号终止语句,并复制与CREATE TABLE语句匹配的内容以保留它。

这是经典的sed符号。由于您正在使用bash,您有可能正在使用GNU sed,需要添加--posix才能使用该符号,或者您需要修改脚本以使用GNU的非标准sed正则表达式。我还没有尝试在输出中插入换行符。如果这对您很重要,您可以使用GNU sed进行操作。

关键点是括号(经典需要用反斜杠转义)是捕获机制,而反斜杠数字是替换机制。


谢谢您的解释,它完全回答了我的问题。 - jesse_galley

6
 sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" dump.sql

测试:

kent$  cat t.txt

CREATE TABLE `orders`
...

CREATE TABLE `foo`
...
...

CREATE TABLE `bar`
...


kent$  sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" t.txt

DROP TABLE IF EXISTS `orders`
 CREATE TABLE `orders`
...

DROP TABLE IF EXISTS `foo`
 CREATE TABLE `foo`
...
...

DROP TABLE IF EXISTS `bar`
 CREATE TABLE `bar`
...

5

0

以下是对此帖子标题进行回答的内容:

正如@bhoom-suktitipat所说:这被称为“反向引用”...

摘要: 通过在替换部分使用反斜杠后跟数字(从1开始),例如:\1,可以实现占位符变量或反向引用查找。

背景:我来到这里是因为我一直在接管一堆代码并改进它。 在这个过程中,我想要预先eslint它,以查找所有JSON键周围的双引号并将其剥离。 ESLint的Quote Props Rule可以使用--fix来执行与我需要做的完全相反的操作。

任务概述:

{"foo": "bar"} 转换为 {foo: "bar"},也就是使用sed命令中的占位符变量

  1. 在第二个匹配组中找到“foo”(键)的等效项:("{1})(\w+)(":{1})
  2. 使用该匹配组作为占位符来呈现foo:,而不是"foo":
  3. 将更改写入文件。

写入不同的文件:

sed -r 's/("{1})(\w+)(":{1})/\2:/g' in.js > out.js

写入同一文件:

sed -ri 's/("{1})(\w+)(":{1})/\2:/g' in-and-out.js

使用的SED标志:

-E,-r,--regexp-extended 在脚本中使用扩展正则表达式 (为了可移植性,请使用POSIX -E)。

-i [SUFFIX],--in-place [= SUFFIX] 直接修改文件(如果提供了SUFFIX,则进行备份)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接