如何使用 sed 替换行的特定部分而不替换行的其余部分?

如何使用 sed 替换行的特定部分而不替换行的其余部分?

假设我有以下文件Product.java

public class Product {
    public String name;
    public String description;
    public String picture;
    public double price;

    public Product(String name, String description, String picture, double price) {
        this.name = name;
        this.description = description;
        this.picture = picture;
        this.price = price;
    }

    public String getName() {
        return this.name;
    }

    public String getDescription() {
        return this.description;
    }

    public String getPicture() {
        return this.picture;
    }

    public double getPrice() {
        return this.price;
    }

    public String toString() {
        return "Product";
    }
}

我目前正在尝试做的是将 中的类字段替换为public的实例,并就地更新文件。因此,替换后,文件应如下所示:privateProduct.java

public class Product {
    private String name;
    private String description;
    private String picture;
    private double price;
    ...
    ...
    ...
}

我尝试通过使用sed以下语句来做到这一点:

sed -ri 's/public [a-zA-Z a-z]*;/private/' Product.java

但是,这只是将类字段替换为private.因此,我想知道如何在保持行的其余部分不变的情况下替换public部分行?private我不确定如何实现这种行为。任何反馈或建议将不胜感激。

答案1

ImHere 已经告诉您如何通过参考替换中的模式部分来解决这个问题,但我想添加一些有用的提示:

  • 不要使用-r扩展的正则表达式语法(顺便说一句,您的原始命令无论如何都没有使用它)。-E是便携式选项。
  • 始终考虑是否涵盖了所有可能的情况。和之间的public int[] fooorpublic String description2换行符怎么样?public;
  • 有时最好通过倒置排除案例地址就像sed '/{/!s/public /private /'替换所有,除非该行public有一个{
  • 最后考虑一下误报,例如评论// don't allow a public setter for this member; it can only be set on instanisation或一些(在本例中是愚蠢的边缘)带有名为 的变量的情况republic,因此您的模式最好是^[[:space:]]*public

总之,一个更强大的脚本可能看起来像

sed '/{/!s/^\([[:space:]]*\)public /\1private /'

相关内容