2015-07-01 20 views
1

我有一个包含文件:

$conf['minified_version'] = 100; 

我想增加与100 SED,所以我有这样的:

sed -r 's/(.*minified_version.*)([0-9]+)(.*)/echo "\1$((\2+1))\3"/ge' 

的问题是这将从原始中删除$conf以及任何缩进间距。我已经能够搞清楚的是,这是因为它试图运行:

echo " $conf['minified_version'] = $((100+1));" 

所以当然它试图与它有没有价值的变量来代替$conf

+0

这里的问题与源代码中的'$'没有任何关系 - 你已经编写了你的​​正则表达式,使得不包含任何文字'$',所以你避免了显而易见的错误在表达式的开始处放置一个线端锚点(一个可以通过'^ [$]'开始避免的陷阱)。相反,它试图让'sed'评估一个shell命令来生成替代内容,它不支持并且从不做。 –

回答

2

这里是一个awk版本:

$ awk '/minified_version/{$3+=1} 1' file 
$conf['minified_version'] = 101 

这寻找包含minified_version的行。任何时候找到这样的一行,第三个字段$3将增加。

+0

谢谢!这是一个相当干净的解决方案 - 它在行尾放弃了分号,但是简单的解决方法就是在数字和分号之间加一个空格 – DAB

1

我对此的建议方法是在磁盘上包含文件,但不包括 minified_version编号。然后,递增这个数字将是简单的:

minified_version=$(< minified_version) 
printf '%s\n' "$((minified_version + 1))" >minified_version 

...你可以只是把印记在源文件中需要在那里要更换。比方说,你有一个名为foo.conf.in文件,其中包含:

$conf['minified_version'] = @[email protected] 

...那么你可以简单地运行,在你的构建过程:

sed -e "s/@[email protected]/$(<minified_version)/g" <foo.conf.in >foo.conf 

这样做的好处是,你永远不会有改变的代码foo.conf.in ,所以你不需要担心覆盖文件内容的错误。这也意味着,如果您将文件检入源代码管理,只要您只检查foo.conf.in而不检查foo.conf,则可避免由于版本号更改附近的上下文而导致潜在合并冲突。


现在,如果你没有想做就地本地操作,这里是用纯天然的bash(从infile读取和写入outfile有点过度设计的方法,只需重命名outfile回来了infile当成功使这就地更换):

target='$conf['"'"'minified_version'"'"'] = ' 
suffix=';' 
while IFS= read -r line; do 
    if [[ $line = "$target"* ]]; then 
    value=${line##*=} 
    value=${value%$suffix} 
    new_value=$((value + 1)) 
    printf '%s\n' "${target}${new_value}${suffix}" 
    else 
    printf '%s\n' "$line" 
    fi 
done <infile >outfile