我正在努力使用sed
替换多个key=value
:
batch_sub () {
local file="${@: -1}" # Last argument is file to be changed.
[[ -w "${file}" ]] || { echo "Invalid file: ${file}" ; return 1 ; }
for arg in "${@}" ; do
[[ $arg =~ (.*)=(.*) ]] || continue
# 'trim_str' will trim leading & trailing spaces.
local key=$(trim_str "${BASH_REMATCH[1]}")
local value=${BASH_REMATCH[2]}
sed -i 's@'"(${key}"' *=).*@1'"${value}"'@' "${file}"
done
}
此功能接受:
之类的参数batch_sub "a = x" "b = y" "c = z" "a.b.d.e=udp://b:8080" "/tmp/file"
效果很好。但是我想要的是接受这样的论点:
batch_sub "a = x b = y c = z a.b.d.e=udp://b:8080" "/tmp/file"
此外,如果仅在此功能中调用sed
一次,那将是很好的:
sed -i -e 's/$key=/1$value/'
-e 's/$key1=/1$value1/'
'/tmp/file'
请建议。
如果仅在此功能中调用一次SED
,那将是不错的
您可以一次致电多次替换。例如
sed -i's/a/a/b/; s/p/q/'
因此,从所有参数中,生成一个字符串,涉及所有替换&然后致电一次。
但是我想要的是接受这样的论点
batch_sub" a = x b = y c = z a.b.d.e = udp://b:8080"/tmp/file"
为什么?
" a = x b = y c = z a.b.d.e = udp://b:8080"对我来说是模糊的。
至少尝试具有对成对的某种定界符,例如
" a = x; b = y; c = z; a.b.d.e = udp://b:8080"
这可能很疯狂。但是使用您设置的要求,也许是这样的:)
#!/bin/bash
declare -r self=${0##*/}
# Left and right trim
trim_str()
{
local tmp="${1##[[:space:]]}"
printf "%s" "${tmp%%[[:space:]]}"
}
# Replace with \, / with /, & with &
sed_esc_repl()
{
local tmp="${1//\/\\}"
tmp="${tmp////\/}"
tmp="${tmp//&/&}"
printf "%s" "$tmp"
}
# Additional escape on search pattern
# escape *.][|
sed_esc_key()
{
local tmp=$(sed_esc_repl "$1")
tmp="${tmp//./.}"
tmp="${tmp//*/*}"
tmp="${tmp//|/|}"
tmp="${tmp//[/[}"
tmp="${tmp//]/]}"
printf "%s" "$tmp"
}
batch_sub()
{
local file=""
local -a argv
local key=
local val=
local sedstr=""
local old_ifs=$IFS
if (( $# < 2 )); then
printf "Usage: $self "replacement pairs" <file>n"
return 1
elif (( $# > 2 )); then
file="${@: -1}"
argv=( "${@:1:$(($#-1))}" ) # Everything but last arg
else
file="$2"
argv=( "$1" )
fi
[[ -w "${file}" ]] || { printf "Invalid file: %sn" "${file}"; return 1; }
# Set IFS to match space and equal sign.
IFS='='' '
for arg in ${argv[@]}; do
if [[ "$key" != "" ]]; then
sedstr+="s/("$(sed_esc_key "$key")") *=.*/1="$(sed_esc_repl "$arg")"/g;"
key=
else
key="$arg"
fi
done
IFS="$old_ifs"
printf "sed string:"%s"nn" "${sedstr%%;}"
sed -i "${sedstr%%;}" "$file"
}
# Create example / test file:
printf "
x[a-zA-Z].*? = mixture1
x[a-zA-Z].*p? = mixture2
x = foo
b*x = fafa
a\\1c = moo
a.b$.d.e=zim zala bim
" > tst
batch_sub "$@"
exit $?
由IE运行:
./keysw" x [a-za-z]。&amp;&amp;猫TST
或
./keysw "x[a-zA-Z].*p? = x"
"b*x = y"
"a1c = zn1"
"a.b$.d.e=udp&://b:8080"
tst && cat tst
给予;
文件:
x[a-zA-Z].*? = mixture1
x[a-zA-Z].*p? = mixture2
x = foo
b*x = fafa
a1c = moo
a.b$.d.e=zim zala bim
结果:
x[a-zA-Z].*? = mixture1
x[a-zA-Z].*p?=x
x = foo
b*x=y
a1c=zn1
a.b$.d.e=udp&://b:8080