【问题标题】:sed replace some pattern with literal expressionsed 用文字表达式替换某些模式
【发布时间】:2016-02-25 03:30:38
【问题描述】:

我有以下 sed 命令:

sed -i 's#^.*BRANCH_NAME=.*$#\tBRANCH_NAME=$(egrep \\"${project}\\" localFile.xml | sed -n 's_.*changeset=\"\([^\"]\+\).*_\1_p')#' myCfgFile.cfg

基本上,我正在尝试将 myCfgFile.cfg 中以 BRANCH_NAME= 开头的行替换为其他内容,例如:BRANCH_NAME=$(egrep \\"${project}\\" localFile.xml | sed -n 's_.*changeset=\"\([^\"]\+\).*_\1_p')

坏消息是我无法按字面意思保留BRANCH_NAME=$(egrep \\"${project}\\" localFile.xml | sed -n 's_.*changeset=\"\([^\"]\+\).*_\1_p') 的内容,因为我得到了解释。

那么,有什么方法可以让内容保持原样,而无需 sed 解释它?正如我上面所说,我正在尝试将一行 (BRANCH_NAME=) 替换为其他内容 (*BRANCH_NAME=$(egrep \"${project} \" localFile.xml | sed -n 's_.changeset=\"([^\"]+)._\1_p')*)

非常感谢您的帮助。 谢谢

编辑

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

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

    • /home/myDir/proj1

    • /home/myDir/proj1/extended

    • (...)

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

<project name="/home/myDir/proj1/extended" path="/home/myDir/proj1/extended" changeset="3c57f20f89de07e1490aac56d1e8aba5848150b5" />

通过执行 for 循环,我得到以下信息:

for project in (cat projectlis); do
   egrep \\"${project}\\" localFile.xml | sed -n 's_.*changeset=\"\([^\"]\+\).*_\1_p')#' myCfgFile.cfg
done
  1. 我不允许更改和提交的 bash 脚本 :) 此脚本确实包含定义变量的错误行

BRANCH_NAME=*

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

BRANCH_NAME=*

BRANCH_NAME=$(egrep \\"${project}\\" localFile.xml | sed -n 's_.*changeset=\"\([^\"]\+\).*_\1_p')`

我希望这更清楚一点。

谢谢

【问题讨论】:

  • 你不觉得这个命令有点复杂吗?您可以转义所有 sed 元字符,请参阅stackoverflow.com/questions/29613304/…,但如果您编辑问题以包含一些示例输入和预期输出并用awk 标记您的问题,我相信有人可以向您展示一个简洁、简单的脚本来做无论你想做什么,都不要通过古怪的转义、管道命令链、子shell等跳过所有的障碍。
  • 您的编辑有点帮助,但现在还是有点模糊。您在第 1 项中描述的文件是您在第 2 项中引用的“projectlis”文件吗?您的 bash 文件是否仅包含其中包含 BRANCH_NAME 的一行? BRANCH_NAME 总是在行首吗?您的 XML 文件是否仅包含 1 行,或者您希望更改其中的多个项目?我无法想象from Jenkins inline script 是什么意思。请编辑您的问题以包含一组清晰的简洁但真正具有代表性的输入文件以及您希望在给定这些输入文件的情况下获得的输出。

标签: regex awk sed


【解决方案1】:

如果没有样本输入和预期输出,这在很大程度上是一个猜测,但看起来你想要做的就是使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 2018-08-22
    • 2013-08-25
    • 1970-01-01
    相关资源
    最近更新 更多