Bash - 替换父匹配中的参数(SED / AWK)

Bash - 替换父匹配中的参数(SED / AWK)

我正在编写一个小脚本来获取一些变量,packageName,newVersion。我在 Google 上搜索并尝试了很多方法,最后我还是想问一下。

脚本执行如下:updatePackage.sh -p weblogic-pkg-1 -v 2.0.1-B3

这读取 yaml:

## Weblogic Deployment
   'weblogic-pkg-1':
     ensure:            'present'
     deploymenttype:    'AppDeployment'
     versionidentifier: '2.0.0-B2'
     timeout:           60
     stagingmode:       "nostage"
     remote:            "1"
     upload:            "1"
     target:
       - "%{hiera('package_clustername')}"
     targettype:
       - 'Cluster'
     localpath:         '/opt/releases/staging/applications/weblogic-pkg-1/weblogic-pkg-1-2.0.0-B2.war'

我尝试让脚本在与包匹配后更改版本号,因此所需的输出是:

## Weblogic Deployment
   'weblogic-pkg-1':
     ensure:            'present'
     deploymenttype:    'AppDeployment'
     versionidentifier: '2.0.1-B3'
     timeout:           60
     stagingmode:       "nostage"
     remote:            "1"
     upload:            "1"
     target:
       - "%{hiera('package_clustername')}"
     targettype:
       - 'Cluster'
     localpath:         '/opt/releases/staging/applications/weblogic-pkg-1/weblogic-pkg-1-2.0.1-B3.war'

YAML 文件包含大约 50 个包,因此很遗憾我无法直接使用 /version/newVersion。系统也非常封闭,因此向操作系统添加 yaml 解析器可能比较棘手。

有小费吗?

谢谢

戴夫

答案1

最后,我用 perl 解决了这个问题。希望这对其他人有所帮助:

#perl -000 -n -i -e "s/versionidentifier: '2.0.0-B1'/versionidentifier: '2.0.0-B3'/m if /\'weblogic-pkg-1\':/; print;" /opt/releases/staging/hiera/dev/deployments/node.corp.yaml

对于目录更新,将分隔符更改为@:

perl -000 -n -i -e "s@localpath:         '/opt/releases/staging/applications/weblogic-pkg-1/weblogic-pkg-1-2.0.0-B1.war''@localpath:         '/opt/releases/staging/applications/weblogic-pkg-1/weblogic-pkg-1-2.0.1-B2.war'@m if /\'vet-common-status-service\':/; print;" /opt/releases/staging/hiera/dev/deployments/node.corp.yaml

答案2

我看到你已经掌握了窍门perl。这就是我建议的:

perl -lape "if (/'weblogic-pkg-1':/../localpath:/ and /versionidentifier|localpath:/) {\$a = \$1 if /\s+versionidentifier: '(.+)'/;s/\$a/2.0.1-B3/}" input.txt

如果你想将其包装在 Bash 脚本中:

#!/usr/bin/env bash

while getopts ":p:v:" opt; do
  case $opt in
    p) p="$OPTARG"
    ;;
    v) v="$OPTARG"
    ;;
    \?) echo "Invalid option -$OPTARG" >&2
    ;;
  esac
done

perl -lape "if (/'$p':/../localpath:/ and /versionidentifier|localpath:/) {\$a = \$1 if /\s+versionidentifier: '(.+)'/;s/\$a/$v/}" input.txt

笔记:我没有包含-i开关,因为它很危险:您应该首先试验并根据您的需要调整脚本,然后再perl -i -lane替换perl -lane

相关内容