如果 n+2 行不包含特定字符串,如何替换匹配字符串

如果 n+2 行不包含特定字符串,如何替换匹配字符串
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.icc.id</groupId>
        <artifactId>idp-parent</artifactId>
        <version>7.0.1.0-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>

    <artifactId>app</artifactId>
    <packaging>war</packaging>
    <name>${project.name} - Hello World Web App</name>

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>solution-commons</artifactId>
            <version>${com.icc.id.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>application-common</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>framework-commons-hazelcast</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>framework-commons-health</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>framework-commons-rabbitmq</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>framework-commons-rest</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>framework-commons-security</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>framework-commons-system</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>framework-commons-web</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>platform-connector-cache</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>platform-connector-spring-remoting</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>platform-openid-connect</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>com.icc.id</groupId>
            <artifactId>platform-rest-commons</artifactId>
            <version>${com.icc.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- The following log4j 1.2 bridge is needed to satisfy libraries that has runtime dependency on log4j 1.2. -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        <dependency>

</project>

所以 pom.xml 可能是这样的。所以要求是扫描每一行并搜索 com.icc.id ,如果找到,则仅当 n+2 行不包含 com.icc.id 时才应进行替换.version(版本行包含 com.icc.id.version)。如果它不包含 - com.icc.id.version,groupid 应替换为 com.uxpsystems.$1(其中 $1 作为参数传递给此脚本)如果包含,则跳过该块并检查下一行是否包含com.icc.id

答案1

由于我们将数据(通过$1)注入到 sed 命令的 rhs 中s///,因此我们需要正确引用它,以便当它插入 sed 代码时,不会触发任何错误。

注意:正如已经向您指出的,解决此问题的正确方法是通过 xml 工具。

$ v1_esc=$(printf '%s\n' "$1" | sed -e 's:[\/&]:\\&:g;$!s/$/\\/')
$ sed -e '
   /com[.]icc[.]id/!b
   $!N;$!N;/\n.*\n/!q
   /.*\n.*\n.*com[.]icc[.]id[.]version/b
   '"s/com[.]icc[.]id\\(.*\\n.*\\n\\)/com.uxpsystems.${var}\\1/"'
' pom.xml

解释:

  • 跳过无趣的行并按原样打印出来。
  • 抓住 3 行,从感兴趣的行开始计数。
  • 在抓取 3 行的过程中,您用完了所有行,这意味着您到达了 eof,然后退出并按原样打印模式空间。
  • 如果我们已经成功到达这里,则意味着我们在模式空间中有 3 条线可供sed查看,其中第一条是有趣的线。
  • 如果第三行中碰巧没有指定的字符串 com.icc.id.version,则跳过处理这 3 行块,并按原样打印它。
  • 我们在这里意味着,最后检测到了正确的 3 行块,现在您应该执行所需的替换。

答案2

这看起来很简单xmlstarlet

#!/bin/sh

xmlstarlet ed -N ns="http://maven.apache.org/POM/4.0.0" -u \
    '//ns:dependency[ns:groupId = "com.icc.id" and not(ns:version = "${com.icc.version}")]/ns:version' \
    -v "com.uxpsystems.$1" file.xml

这将选择所有version带有文本的节点,除了那些也具有带有文本的节点${com.icc.version}的节点的子节点。选定的节点全部更新为包含 text ,其中是为脚本提供的第一个参数。dependencygroupIDcom.icc.idversioncom.uxpsystems.$1$1

答案3

解析器或将行加载到缓冲区中,如下所示:

awk '{line=line1;
      line1=line2;
      line2=$0;}
     /com.icc.id.version/ { if (line ~ "com.icc.id")
       { line = ... replace ... }
     }
     {print line}
     END {print line1; print line}'

注意:我没有测试过,但应该非常接近

相关内容