2015-07-01 19 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