【问题标题】:Sed: Append before the last occurrence of a charactersed:在最后一次出现的字符之前追加
【发布时间】:2017-07-11 22:24:13
【问题描述】:

假设我有以下文件:

public class Foo {
   // Some code
   // There will be functions here, so there are other {}

   // I WANT TO INSERT HERE
}

我想在Foo 类中插入一个函数。这正好在最后一次出现} 之前。

如何在 sed 中做到这一点?

编辑

一个同时适用于 Mac 和 Linux 的脚本怎么样?

【问题讨论】:

  • 不止一个 } 吗?如果不使用 $Yourstuff } 替换 } 像这样 sed "s/}/$yourstuff }/"
  • @MikeWodarczyk,是的,还会有更多}
  • 是否有多个} 前面没有空格?
  • 你能把字符串“//我想在这里插入”放到文件中吗?然后你可以用你想去的地方替换这个字符串。
  • 目前尚不清楚如何将关闭类的} 与文件中可能存在的任何其他} 区分开来。您确实需要可以解析文件中任何语言的东西,而不是正则表达式。

标签: bash sed


【解决方案1】:
sed '$s/\(}\)/Put thing here\n\1/' 

前面的$ 直接匹配最后一行,因此如果 } 不在文件的最后一行,它将不起作用。

【讨论】:

  • 如有必要,请随意投反对票。我已经明确指定了我的 sed 何时可以工作。我在 } 是否在最后一行的问题中没有看到足够的信息,所以只为简单的情况提供一个简单的答案。
  • 不,我不能那样做,我并不是在批评你的努力,只是 OS X 上的行为将字符串放在最后一个 } 之前的 {} 中。
  • 对不起...我不知道。我使用 GNU sed 在 linux 上对此进行了测试。
  • @l'L'l - 不,OS X 使用来自 FreeBSD 的 sed,根本不是 GNU sed。也许你在想grep
  • @ghoti:也许就是这样;我的观点是同一个工具可能因平台而异(在操作和结果上)。 OP 没有指定他们使用的是哪个,但无论如何都可能需要注意。
【解决方案2】:

假设文件中有多个类和可能的其他数据:

sed '/Foo/,/^}/s%^}%\t//New insert\n}%' file

在一天结束时,您总能找到与您的解决方案不太相符的东西,因此您可能需要了解您的数据 :)

下面也将在一行中处理类定义:

sed -e '/Foo/,/^}/s%^}%\t//New insert\n}%' -e '/Foo.*}$/s%}$%\t //New insert\n}%' file

【讨论】:

  • 如果类都是一行(例如class { ... {} }),这不起作用...在sed的某些版本上\t\n最终会打印只是 tn 而不是制表符/新行。
【解决方案3】:

这可以在 RedHat 使用 GNU Sed 4.2.2 完成工作(如果您愿意,可以测试它here

$ sed -n '/class Foo2 {/,/^}$/{s/^}$/Insert here\n\0/};p' file

我假设该文件可能包含更多类,并且我尝试在文件中间的类 Foo2 末尾之前插入我的文本(在此处插入)。

测试:

$ cat file2
public class Foo {
   // Some code
   // There will be functions here, so there are other {}
}
public class Foo2 {
   // Some code
   // There will be functions here, so there are other {}
}
public class Foo3 {
   // Some code
   // There will be functions here, so there are other {}
}


$ sed -n '/class Foo2 {/,/^}$/{s/^}$/Insert here\n\0/};p' file2
public class Foo {
   // Some code
   // There will be functions here, so there are other {}
}
public class Foo2 {
   // Some code
   // There will be functions here, so there are other {}
Insert here
}
public class Foo3 {
   // Some code
   // There will be functions here, so there are other {}
}

说明:
/class Foo2 {//^}$/ - 范围 - 从class name Foo2 { 到第一个^}$
{s/^}$/Insert here\n\0/} - 替换部分。将^}$ 替换为your text 加上new line 加上替换部分\0
;p:打印

BSD 更新
在@ghoti 的出色帮助下,在设置 FreeBSD 机器进行测试之后,这似乎可以在 FreeBSD 上运行(仅限 bash):

sed -n "/class Foo2 {/,/^}\$/{s/^}\$/Insert here \\"$'\n'" &/;};p" file

请注意,如果 shell 不是 bash,这将不起作用。反正你可以试一试。

【讨论】:

  • @Kousha 嗯...不好。我也尝试使用 sed --posix 并且工作正常。你用什么 sed 版本?
  • @Kousha 顺便说一句,你知道你可以在你的 mac 上安装 gsed = gnu sed,对吧? stackoverflow.com/questions/30003570/…
  • 脚本可以在非 GNU sed 中正常工作,只需进行简单的调整,在 GNU sed 中也可以。可移植性是让您的代码在一种语言的多个实现中运行,而不是让特定实现在多个系统中无处不在。
  • @ghoti 你说得对,好的代码必须是可移植的。我是一个业余爱好者,我无法在非 GNU sed 上测试我的脚本......如果你知道如何测试它,我愿意修复它。 PS:我没有找到任何配备非GNU sed的在线终端进行必要的调整(即类似于我使用的tutorialspoint bash在线终端)
  • @ghoti 顺便说一句,我觉得奇怪的是,这个脚本使用 --posix 开关成功运行,理论上禁用 gnu 扩展。显然 gnu sed --posix 与非 gnu sed 有更多的区别。
【解决方案4】:

试试这个:

sed -i '/^\(}\)/ i new_function' file

在 Debian 上为我工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多