Regex sed用文本表达式替换某些模式

Regex sed用文本表达式替换某些模式,regex,awk,sed,Regex,Awk,Sed,我有以下sed命令: sed -i 's#^.*BRANCH_NAME=.*$#\tBRANCH_NAME=$(egrep \\"${project}\\" localFile.xml | sed -n 's_.*changeset=\"\([^\"]\+\).*_\1_p')#' myCfgFile.cfg 基本上,我试图用另一个类似于:BRANCH\u NAME=$(egrep\\\“${project}\\”localFile.xml;sed-n's.*.changeset=\([^\“

我有以下sed命令:

sed -i 's#^.*BRANCH_NAME=.*$#\tBRANCH_NAME=$(egrep \\"${project}\\" localFile.xml | sed -n 's_.*changeset=\"\([^\"]\+\).*_\1_p')#' myCfgFile.cfg
基本上,我试图用另一个类似于:
BRANCH\u NAME=$(egrep\\\“${project}\\”localFile.xml;sed-n's.*.changeset=\([^\“]\+\).\u1\u p')的东西来替换myCfgFile.cfg中以BRANCH\u NAME=开头的一行

坏消息是,我不能按字面意思保留
BRANCH\u NAME=$(egrep\\“${project}\\”localFile.xml | sed-n的.*changeset=\”\([^\“]\+\).\\u\1\u p')
的内容,因为我得到了解释

那么,有没有什么方法可以让内容保持原样,而不用sed进行解释?正如我上面所说的,我正在尝试用其他(*BRANCH\u NAME=$(egrep\“${project}\”localFile.xml;sed-n's.changeset=\”([^\“]+).\u1\u p')*)来替换一行(BRANCH\u NAME=

我非常感谢你的帮助。 谢谢

编辑

实际上,我正在处理3个文件:

  • 一个项目路径列表(以下是格式)

    • /主页/myDir/proj1

    • /主页/myDir/proj1/extended

    • (……)

  • 包含项目名称及其相应变更集的.xml文件

  • 不允许我更改和提交的bash脚本:) 此脚本包含定义变量的错误行
  • 分行名称=*

    在执行不允许提交的脚本之前,我想(从Jenkins内联脚本)更改错误的行

    分行名称=*

    我希望这更清楚一点


    谢谢

    没有示例输入和预期输出,这只是一个猜测,但看起来您正试图使用awk执行以下操作:

    awk -v project="$project" '
    NR==FNR {
        if ($0 ~ project) {
            gsub(/.*changeset="|".*/,"")
            branchName = $0
        }
        next
    }
    /BRANCH_NAME/ { $0 = "\tBRANCH_NAME=" branchName }
    { print }
    ' localFile.xml myCfgFile.cfg > tmp && mv tmp myCfgFile.cfg
    
    一旦我们看到您的输入文件,它可能会比这更简单

    我仍然无法从您的问题中找出您的输入文件真正包含的内容或您真正希望脚本输出的内容,但鉴于您目前告诉我们的内容,这可能会告诉您如何执行您正在尝试执行的操作:

    $ cat projectlis   
    /home/myDir/proj1
    /home/myDir/proj1/extended
    
    $ cat localFile.xml                                    
    <project name="/home/myDir/proj1/extended" path="/home/myDir/proj1/extended" changeset="3c57f20f89de07e1490aac56d1e8aba5848150b5" />
    <project name="/home/myDir/proj1" path="/home/myDir/proj1" changeset="something-made-up" />
    
    $ cat myCfgFile.cfg                                     
    BRANCH_NAME=*
    
    $ cat tst.awk                                           
    FILENAME==ARGV[1] {
        proj2branch[$0]
        next
    }
    FILENAME==ARGV[2] {
        for (proj in proj2branch) {
            if ( index($0,"name=\"" proj "\"") ) {
                gsub(/.*changeset="|".*/,"")
                proj2branch[proj] = $0
            }
        }
        next
    }
    /BRANCH_NAME/ {
        for (proj in proj2branch) {
            print proj":", "BRANCH_NAME=" proj2branch[proj]
        }
    }
    
    $ awk -f tst.awk projectlis localFile.xml myCfgFile.cfg                                                                                
    /home/myDir/proj1/extended: BRANCH_NAME=3c57f20f89de07e1490aac56d1e8aba5848150b5
    /home/myDir/proj1: BRANCH_NAME=something-made-up
    
    $cat projectlis
    /主页/myDir/proj1
    /主页/myDir/proj1/extended
    $cat localFile.xml
    $cat myCfgFile.cfg
    分行名称=*
    $cat tst.awk
    FILENAME==ARGV[1]{
    项目分行[$0]
    下一个
    }
    FILENAME==ARGV[2]{
    适用于(项目j2分公司中的项目){
    如果(索引($0,“名称=\”项目“\”)){
    gsub(/.*changeset=“|”。*/,”)
    项目2分支机构[项目]=0美元
    }
    }
    下一个
    }
    /分行名称/{
    适用于(项目j2分公司中的项目){
    打印项目“:”,“分支机构名称=“项目分支机构[项目]
    }
    }
    $awk-f tst.awk projectlis localFile.xml myCfgFile.cfg
    /home/myDir/proj1/extended:分支机构名称=3c57f20f89de07e1490aac56d1e8aba5848150b5
    /home/myDir/proj1:BRANCH\u NAME=虚构的东西
    
    如果没有示例输入和预期输出,这只是一个猜测,但看起来您尝试使用awk做的就是这样:

    awk -v project="$project" '
    NR==FNR {
        if ($0 ~ project) {
            gsub(/.*changeset="|".*/,"")
            branchName = $0
        }
        next
    }
    /BRANCH_NAME/ { $0 = "\tBRANCH_NAME=" branchName }
    { print }
    ' localFile.xml myCfgFile.cfg > tmp && mv tmp myCfgFile.cfg
    
    一旦我们看到您的输入文件,它可能会比这更简单

    我仍然无法从您的问题中找出您的输入文件真正包含的内容或您真正希望脚本输出的内容,但鉴于您目前告诉我们的内容,这可能会告诉您如何执行您正在尝试执行的操作:

    $ cat projectlis   
    /home/myDir/proj1
    /home/myDir/proj1/extended
    
    $ cat localFile.xml                                    
    <project name="/home/myDir/proj1/extended" path="/home/myDir/proj1/extended" changeset="3c57f20f89de07e1490aac56d1e8aba5848150b5" />
    <project name="/home/myDir/proj1" path="/home/myDir/proj1" changeset="something-made-up" />
    
    $ cat myCfgFile.cfg                                     
    BRANCH_NAME=*
    
    $ cat tst.awk                                           
    FILENAME==ARGV[1] {
        proj2branch[$0]
        next
    }
    FILENAME==ARGV[2] {
        for (proj in proj2branch) {
            if ( index($0,"name=\"" proj "\"") ) {
                gsub(/.*changeset="|".*/,"")
                proj2branch[proj] = $0
            }
        }
        next
    }
    /BRANCH_NAME/ {
        for (proj in proj2branch) {
            print proj":", "BRANCH_NAME=" proj2branch[proj]
        }
    }
    
    $ awk -f tst.awk projectlis localFile.xml myCfgFile.cfg                                                                                
    /home/myDir/proj1/extended: BRANCH_NAME=3c57f20f89de07e1490aac56d1e8aba5848150b5
    /home/myDir/proj1: BRANCH_NAME=something-made-up
    
    $cat projectlis
    /主页/myDir/proj1
    /主页/myDir/proj1/extended
    $cat localFile.xml
    $cat myCfgFile.cfg
    分行名称=*
    $cat tst.awk
    FILENAME==ARGV[1]{
    项目分行[$0]
    下一个
    }
    FILENAME==ARGV[2]{
    适用于(项目j2分公司中的项目){
    如果(索引($0,“名称=\”项目“\”)){
    gsub(/.*changeset=“|”。*/,”)
    项目2分支机构[项目]=0美元
    }
    }
    下一个
    }
    /分行名称/{
    适用于(项目j2分公司中的项目){
    打印项目“:”,“分支机构名称=“项目分支机构[项目]
    }
    }
    $awk-f tst.awk projectlis localFile.xml myCfgFile.cfg
    /home/myDir/proj1/extended:分支机构名称=3c57f20f89de07e1490aac56d1e8aba5848150b5
    /home/myDir/proj1:BRANCH\u NAME=虚构的东西
    
    您不觉得这个命令有点复杂吗?你可以跳过所有的sed元字符,请参见,但是如果你编辑你的问题以包含一些示例输入和预期输出,并用
    awk
    标记你的问题,我相信有人可以向你展示一个简洁、简单的脚本来做你想做的任何事情,而不必通过古怪的转义跳过所有的障碍,管道命令链、子shell等。您的编辑有点帮助,但现在仍然有点模糊。您在第1项中描述的文件是否是您在第2项中提到的“projectlis”文件?bash文件是否只包含一行分支名称?分支机构名称是否始终位于行的开头?您的XML文件是否只包含一行,还是希望更改其中的多个项目?我无法想象Jenkins内联脚本的
    意味着什么。请编辑您的问题,使其包含一组简洁但真正具有代表性的输入文件,以及给定这些输入文件时希望获得的输出。您不觉得该命令有点复杂吗?你可以跳过所有的sed元字符,请参见,但是如果你编辑你的问题以包含一些示例输入和预期输出,并用
    awk
    标记你的问题,我相信有人可以向你展示一个简洁、简单的脚本来做你想做的任何事情,而不必通过古怪的转义跳过所有的障碍,管道命令链、子shell等。您的编辑有点帮助,但现在仍然有点模糊。您在第1项中描述的文件是否是您在第2项中提到的“projectlis”文件?bash文件是否只包含一行分支名称?分支机构名称是否总是在开头
    $ cat projectlis   
    /home/myDir/proj1
    /home/myDir/proj1/extended
    
    $ cat localFile.xml                                    
    <project name="/home/myDir/proj1/extended" path="/home/myDir/proj1/extended" changeset="3c57f20f89de07e1490aac56d1e8aba5848150b5" />
    <project name="/home/myDir/proj1" path="/home/myDir/proj1" changeset="something-made-up" />
    
    $ cat myCfgFile.cfg                                     
    BRANCH_NAME=*
    
    $ cat tst.awk                                           
    FILENAME==ARGV[1] {
        proj2branch[$0]
        next
    }
    FILENAME==ARGV[2] {
        for (proj in proj2branch) {
            if ( index($0,"name=\"" proj "\"") ) {
                gsub(/.*changeset="|".*/,"")
                proj2branch[proj] = $0
            }
        }
        next
    }
    /BRANCH_NAME/ {
        for (proj in proj2branch) {
            print proj":", "BRANCH_NAME=" proj2branch[proj]
        }
    }
    
    $ awk -f tst.awk projectlis localFile.xml myCfgFile.cfg                                                                                
    /home/myDir/proj1/extended: BRANCH_NAME=3c57f20f89de07e1490aac56d1e8aba5848150b5
    /home/myDir/proj1: BRANCH_NAME=something-made-up