当源包含 $ 时如何用 sed 替换
how to replace with sed when source contains $
我有一个文件包含:
$conf['minified_version'] = 100;
我想用 sed 增加 100,所以我有这个:
sed -r 's/(.*minified_version.*)([0-9]+)(.*)/echo "$((+1))"/ge'
问题在于,这会从原始文件中删除 $conf
以及任何缩进间距。我能够弄清楚的是,这是因为它试图 运行:
echo " $conf['minified_version'] = $((100+1));"
所以它当然会尝试用一个没有值的变量替换 $conf
。
我建议的方法是在磁盘上创建一个文件,其中 只包含 minified_version 号码。然后,递增该数字将非常简单:
minified_version=$(< minified_version)
printf '%s\n' "$(( minified_version + 1 ))" >minified_version
...您可以在需要替换的源文件中放置一个印记。假设您有一个名为 foo.conf.in
的文件,其中包含:
$conf['minified_version'] = @MINIFIED_VERSION@
...那么您可以简单地 运行,在您的构建过程中:
sed -e "s/@MINIFIED_VERSION@/$(<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
这是一个 awk 版本:
$ awk '/minified_version/{+=1} 1' file
$conf['minified_version'] = 101
这将查找包含 minified_version
的行。每当找到这样的一行时,第三个字段
将递增。
我有一个文件包含:
$conf['minified_version'] = 100;
我想用 sed 增加 100,所以我有这个:
sed -r 's/(.*minified_version.*)([0-9]+)(.*)/echo "$((+1))"/ge'
问题在于,这会从原始文件中删除 $conf
以及任何缩进间距。我能够弄清楚的是,这是因为它试图 运行:
echo " $conf['minified_version'] = $((100+1));"
所以它当然会尝试用一个没有值的变量替换 $conf
。
我建议的方法是在磁盘上创建一个文件,其中 只包含 minified_version 号码。然后,递增该数字将非常简单:
minified_version=$(< minified_version)
printf '%s\n' "$(( minified_version + 1 ))" >minified_version
...您可以在需要替换的源文件中放置一个印记。假设您有一个名为 foo.conf.in
的文件,其中包含:
$conf['minified_version'] = @MINIFIED_VERSION@
...那么您可以简单地 运行,在您的构建过程中:
sed -e "s/@MINIFIED_VERSION@/$(<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
这是一个 awk 版本:
$ awk '/minified_version/{+=1} 1' file
$conf['minified_version'] = 101
这将查找包含 minified_version
的行。每当找到这样的一行时,第三个字段 将递增。