【问题标题】:Replacing string within a file using bash + environmental variables使用bash +环境变量替换文件中的字符串
【发布时间】:2015-01-29 00:04:05
【问题描述】:

为了简单起见,假设我有一个文件(请原谅我无用的伪代码)

文件.txt

std::string filename = "filename.txt"

double v_no = 2.0;

const int v_minor = 0; // < --- Target

std::string random_var1 = "Hello"
std::string random_var2 = "Hello 2"

int main()
{
    // .. 
}

我在同一目录中有一个 bash 文件 - set_version.sh

我想用这个脚本替换这个文件中的一个字符串——特别是用“v_minor = $VARIABLE”替换“v_minor = 0”——在我的例子中,变量将是服务器上的一个环境集。

可以说它已经成功运行了几次。现在字符串显示为“v_minor = 2”。我仍然希望相同的 set_version.sh 脚本将 2 更改为变量。

在我的软件的 Windows 版本中,我有一个将“v_minor = %d”更改为“v_minor = %VERSION%”的批处理文件。

我的问题是我如何在 bash 中做类似的事情?例如。忽略字符串中的小数点并将其更改为变量。

到目前为止我得到了什么:

set_version.sh

#!/bin/bash

VERSION=75

sed -i '' 's/v_minor = %d/v_minor = $VERSION/g/' file.txt

设置的版本 var 仅用于测试目的。

这会返回错误

sed: 1: "s/v_minor = %d/v_minor  ...": bad flag in substitute command: '/'

我正在为这个测试运行 Mac OS X Yosemite。

同样,本质上 %d 可以是任何整数。

谢谢

【问题讨论】:

  • 只是为了确认,%d不会匹配“任何整数”,你需要使用[[:digit:]][[:digit:]]*。祝你好运。

标签: c bash shell unix sed


【解决方案1】:

这对你有用:

sed -i '' "s/v_minor = .*$/v_minor = $VERSION/g" file.txt

.*$ 表示直到该字符串的末尾。 操作变量时不要忘记使用" "。

【讨论】:

    【解决方案2】:
    sed -i '' 's/v_minor = %d/v_minor = $VERSION/g/' file.txt
    #                                             ^
    #                                            /
    #                       remove this slash ---
    

    【讨论】:

      【解决方案3】:

      根据您的描述,我建议另一种更简单的方法如下(简单会减少错误...):

      首先,将目标更改为

      const int v_minor = V_MINOR; // < --- Target
      

      其次,在目标语句之前的任意位置添加一个包含行:

      #include "version.h"
      

      三、编写脚本,生成类似如下的version.h:

      #ifndef _VERSION_H_
      #define V_MINOR  0           // <== this 0 is what you want to change.
      #endif
      

      生成一个脚本来输出所说的version.h太简单了(只是一些固定的打印加上目标号)。因此,我不在这里提供。

      与那些可能容易出错的 sed-awk-perl 解决方案相比,我更喜欢这种简单的解决方案。

      【讨论】:

      • 极端的说版本行可能是这样的:const int v_minor = /* version */ 0;一个简单的sed/awk不能轻易保留那些cmets并替换0,并不是说可以放置0在下一行,即“第一行:v_minor =,和“第二行:0;。这将需要解析器理解 C 语言语法。甚至等号 ('=') 周围的空格也会产生问题,更不用说像 if (v_minor == 5) 这样的一些用法会被 sed/awk 错误解析,将第二个 = 替换为目标编号会导致编译时错误。
      • 这似乎是一种更有效/更少hacky的方式。我也可以在 Windows 版本上轻松做到这一点。谢谢。
      • 此外,不是总是更改“.h”文件,而是可以在构建时传递版本,例如,“make ... -D{var}={value}...” ;这更常见于内部版本号,但您也可以通过这种方式从环境中获取版本号,例如从 txt 文件或 git 等。
      • Atlassian Bamboo 负责处理我的构建 + 开发版本。基本上我正在做的是在 Bamboo "VERSION=${bamboo.buildNumber}" 中设置一个环境变量。然后通过将 VERSION 解析到头文件中来在我的软件中引用它。将 version.h 中的变量设置为bamboo.buildNumber 的脚本在 Bamboo 构建时执行 - 就在我的 make + 打包执行之前。
      猜你喜欢
      • 1970-01-01
      • 2020-12-21
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 2014-02-16
      • 1970-01-01
      相关资源
      最近更新 更多