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

时间:2012-10-15 15:30:14

标签: bash sed awk

我想将匹配结果的特定部分存储为稍后用于替换的变量。我想把它保存在一个班轮中,而不是事先找到我需要的变量。

配置apache并使用mod_rewrite时,您可以指定要用作变量的模式的特定部分,如下所示:

RewriteRule ^www.example.com/page/(.*)$ http://www.example.com/page.php?page=$1 [R=301,L]

括号内包含的模式匹配部分存储为$ 1以供日后使用。因此,如果网址为www.example.com/page/home,则会将其替换为www.example.com/page.php?page=home。所以比赛的“主场”部分保存在$ 1中,因为它是括号内部模式的一部分。

我希望使用sed命令这样的功能,我需要自动替换SQL转储文件中的许多字符串,如果在每个create table之前存在命令,则添加drop table,但我需要知道表要执行此操作的名称,因此如果转储文件包含以下内容:

...
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 个答案:

答案 0 :(得分:10)

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做到这一点,如果它对你来说足够重要的话。

关键点是括号(通常需要使用反斜杠进行转义)是捕获机制,反斜杠数是替换机制。

答案 1 :(得分: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`
...

答案 2 :(得分:1)

这称为&#34;后退参考&#34;。并且sed将开始在括号之间编号。 \(... \)

请注意使用反斜杠作为上面的转义字符。

参考:https://www.gnu.org/software/sed/manual/html_node/Regular-Expressions.html

答案 3 :(得分:0)

以下是通过该线程的标题回答OP的问题: 如@ bhoom-suktitipat所述:这称为“反向引用” ...

摘要: 在替换端,通过使用反斜杠后跟一个从1开始的数字来实现占位符变量或向后引用查找,如下所示:\1

背景:我在这里是因为我一直在学习一堆代码并对其进行修改。在此过程中,我想预先添加标签以查找JSON密钥周围的所有双引号并将其删除。 ESLint's Quote Props Rule可与--fix一起使用,与我需要做的完全相反。

任务概述:

{ "foo": "bar" }{ foo: "bar" }中,也就是在占位符命令中使用占位符变量

  1. 在第二个匹配组("{1})(\w+)(":{1})中查找与“ foo”(键)等效的内容。
  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 use extended regular expressions in the script (for portability use POSIX -E).

-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if SUFFIX supplied)