2014-12-01 2 views
-2

Скажут, ради простоты у меня есть файл (пожалуйста, простите мой бесполезный псевдокод)Замена строки в файл с помощью Баша + переменных окружений

file.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() 
{ 
    // .. 
} 

И у меня есть файл Баш в том же каталоге - set_version.sh

Я хочу заменить строку в этом файле этим скриптом - в частности «v_minor = 0» на «v_minor = $ VARIABLE» - в моем случае переменная будет экологическим сервер.

Так что скажем, что он был успешно запущен пару раз. Теперь строка читает «v_minor = 2». Я все еще хочу, чтобы один и тот же скрипт set_version.sh менял 2 на любую переменную.

В окне сборки моего программного обеспечения у меня есть пакетный файл, который изменяет «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 

Version вар существо набор только для целей тестирования.

Это возвращает ошибку

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

Я бегу Mac OS X Yosemite для этого теста.

Опять же, по существу,% d может быть любым целым числом.

Спасибо

+1

только для подтверждения, '% d' не будет соответствовать ни одному целому числу, вам нужно использовать' [[: digit:]] [[: digit:]] * '. Удачи. – shellter

ответ

2

Это будет работать для вас:.

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

* $ означает, что до конца этой строки. Не забудьте использовать " " при работе с переменными.

1
sed -i '' 's/v_minor = %d/v_minor = $VERSION/g/' file.txt 
#           ^
#           /
#      remove this slash --- 
+0

это не поможет ему – tinySandy

1

По вашему описанию, я хотел бы предложить еще один простой способ следующим образом (и простота сделает меньше ошибок ...):

Во-первых, Измени цель

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, я предпочитаю это простое решение.

+0

Строго говоря, строка версии может выглядеть так: 'const int v_minor =/* version */0;' Простое sed/awk не может легко сохранить эти комментарии и заменить '0', не сказать, что '0' можно поместить в следующую строку, то есть« Первая строка: 'v_minor =' и «Вторая строка:' 0; '. Для этого потребуется синтаксис синтаксического анализатора синтаксического анализатора. Даже пространства вокруг знака равенства ('=') могут создавать проблемы, не говоря уже о некотором использовании, например 'if (v_minor == 5)', можно ошибочно проанализировать sed/awk, заменив второй '=' на целевой номер вызывая ошибку времени компиляции. –

+0

Это похоже на гораздо более эффективный/менее хакерский способ сделать это. И что-то, что я могу легко сделать и с версией Windows. Спасибо. – maxtuzz

+0

Кроме того, вместо изменения файла «.h» версия может быть передана во время сборки, например «make ... -D {var} = {value} ...»; это чаще всего делается для чисел сборки, но вы также можете получить свой номер версии из среды таким образом, например, из txt-файла или из git и т. д. – michael

Смежные вопросы