【问题标题】:Regex to repeat indentation in sed正则表达式在 sed 中重复缩进
【发布时间】:2012-11-17 19:05:21
【问题描述】:

这就是我想做的:

如果我遇到类似的模式

someVarX: val1

我要插入

someVarY: val2

在下一行

...但问题是:

someVarX: val1 可以在空格(缩进)之前有一个数字,计数在 0 和 N 之间的任意位置,我还想在下一行重复该确切的缩进。因此,如果 someVarX: val1 前面有 3 个空格,那么我也希望 someVarY: val2 前面有 3 个空格。

这是我尝试过的:

s/\n( +)someVarX: val1/\n${1}someVarX: val1\n${1}someVarY: val2/

希望 ${1} 将搜索模式中的捕获组插入替换字符串,但得到:

sed: command garbled: ...

操作系统 os SunOS 5.10。我无法运行sed --version,它告诉我选项--version 是非法的。

有什么想法吗?

【问题讨论】:

  • 捕获组被引用为\1。此外,在您的匹配模式中,'\n' 是否意味着换行?除非您在保持缓冲区上进行操作,否则这将不起作用。对于您似乎正在尝试的内容(您的问题中的示例输入和所需输出使此类事情变得更容易帮助解决,现在我们必须假设我们知道您希望它如何工作)。
  • 是的,\n 是新行。我还能如何指示它插入新行?
  • 1.请编辑您的问题以包含uname 和sed --version 的结果。一些 seds 允许在替换部件中使用 \n。我对\n 的反对意见在第一部分,s/\n( +) someVar... 中的模式匹配。 2. sed 依赖\n 将每一行分开处理,它不会在行的存在。 \n 在模式匹配方面唯一起作用的地方是当您将一行保存到保持缓冲区中时......所以...... 3.您向我们展示了您的完整 sed 脚本吗?祝你好运。
  • 更新:操作系统 os SunOS 5.10。我无法运行 sed --version,它告诉我选项 --version 是非法的。
  • 大多数人认为整个世界都围绕着 Linux。我认为@Thor 的便携式答案应该适用于 Sun。 (使用 Solaris 的标签并包括示例输入和所需的输出,您会得到更及时的响应。)祝你好运

标签: regex sed solaris


【解决方案1】:

假设您的输入类似于:

<< EOF > infile
someVarX: val1
   someVarX: val1
 someVarX: val1
    someVarX: val1
EOF

您可以像这样完成它(使用 GNU sed ERE 测试):

<infile sed -r 's/^( *)someVarX: .*/&\n\1someVarY: val2/'

与 BRE 和更便携的选项相同(也使用 FreeBSD sed 进行了测试):

sed '/^ *someVarX: .*/ { G; s/^\( *\)someVarX: .*/&\1someVarY: val2/; }' infile

输出:

someVarX: val1
someVarY: val2
   someVarX: val1
   someVarY: val2
 someVarX: val1
 someVarY: val2
    someVarX: val1
    someVarY: val2

注意,使用^ 将正则表达式锚定在行首,而不是\n,因为sed 永远不会在输入中看到换行符。也可以使用*,除非行首总是有空格。

替换中的和号 (&amp;) 被整个匹配替换,反向引用 (\1) 插入适量的空格。

【讨论】:

  • 我将正则表达式与其他正则表达式(有效)一起设置在 sed S&R 文件中。我试过了,但没有用:s/( *)someVarX: val1/\1someVarX: val1&amp;\n\1someVarX: val1/
  • @foampile:您使用的是基本正则表达式还是扩展正则表达式?另请注意,您正在复制 someVarX,&amp; 将扩展为 \1someVarX: val1。
  • 改成s/^( *)someVarX: .*/&amp;\n\1someVarY: val2/后还是command garbled
  • @foampile:试试我刚刚添加的更便携的版本。
  • 版本中新行插入在哪里?
【解决方案2】:

这适用于任何 sed:

sed -n 'p;s/^\([ \t]*\)someVarX: val1/\1someVarY: val2/p' file

如果你想要更可扩展的东西,这里是 awk 解决方案:

awk '1; /^[ \t]*someVarX: val1/{ sub(/[^ \t].*/,"someVarY: val2"); print}' file

【讨论】:

  • 查看我刚刚发布的答案
【解决方案3】:

这终于奏效了:

        s/^\( *\)someVarX: val1/&\
\1someVarY: val2/

必须在 sed S&R 规范文件的两行中完成,我们称之为 snrspec.sed,其中还包含其他 S&R 说明:

1,/^END/{
        s/ABC/XYZ/

        ...

        s/^\( *\)someVarX: val1/&\
\1someVarY: val2/

}

然后我调用了 sed:

sed -f snrspec.sed inputfile.txt > outputfile.txt

但是,如果有人知道怎么做,我更愿意在一行中完成,因为它显然会更优雅。但上述方法奏效了,我执行了大规模的 S&R 操作。

【讨论】:

  • 在一行上进行多次替换会更优雅一点并不明显,我认为从文件中运行脚本是一种更明智的方法。
【解决方案4】:

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

sed '/someVarX: val1/{h;G;s//someVarY: val2/2}' file

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多