有许多问题询问如何在sed模式中使用变量,例如:sed "s/re/$VAR/" file
,但我想在变量上执行替换。到目前为止,我一直在使用echo
来执行此操作:
echo "$VAR" | sed 's/re/new/'
但是,虽然这有效但看起来很混乱。在bash或zsh中有更简单/更优雅的方法吗?
答案 0 :(得分:4)
你可以这样做:
sed 's/re/new' <<< "$var"
如果你想这样做并更新变量,你可以这样做:
var=$(sed 's/re/new' <<< "$var")
答案 1 :(得分:1)
如果您不想使用sed,可以使用“parameter expansion”进行搜索并在参数内替换;引用Bash手册:
${parameter/pattern/string}扩展模式以生成与文件名一样的模式 扩张。 参数已展开,并且 pattern 的最长匹配 反对其值将替换为 string 。
如果 pattern 以
/
开头,则 pattern 的所有匹配项都会被替换 使用字符串。通常只替换第一场比赛。如果模式 从#
开始,它必须在展开值的开头匹配 of 参数。如果 pattern 以%
开头,则必须在结尾处匹配 参数的扩展值。如果 string 为null,则删除 pattern 的匹配项并
/
可以省略以下模式。如果参数为@
或*
,则为 替换操作应用于每个位置参数 转,扩展是结果列表。如果参数是 用@
或*
下标的数组变量,替换操作 依次应用于数组的每个成员,扩展为 结果清单。
参数扩展不仅限于这种替换,还有更多,请参阅手册。
一些例子
为了便于阅读而放弃引用。
简单变量
$ var='abcabc'
$ echo ${var/a/X} # Replace first 'a'
Xbcabc
$ echo ${var//a/X} # Replace all 'a'
XbcXbc
$ echo ${var/a} # Remove 'a'
bcabc
$ echo ${var//a} # Remove all 'a'
bcbc
$ echo ${var/#b} # Try to remove 'b' from start of string - no-op
abcabc
$ echo ${var/#a} # Remove 'a' from start of string
bcabc
$ echo ${var/%b} # Try to remove 'b' from end of string - no-op
abcabc
$ echo ${var/%c} # Remove 'c' from end of string
abcab
位置参数
$ set -- abcabc defdef abcabc # Set $1, $2 and $3
$ echo ${@/a/X} # Replace first 'a' for each parameter
Xbcabc defdef Xbcabc
$ echo ${@//a/X} # Replace all 'a' for each parameter
XbcXbc defdef XbcXbc
$ echo ${@/?/X} # Replace first occurrence of any character
Xbcabc Xefdef Xbcabc
$ echo ${@//?/X} # Replace all characters
XXXXXX XXXXXX XXXXXX
阵列
$ arr=(abcabc defdef abcabc) # Create array
$ echo ${arr[@]/a/X} # Replace first 'a' in each element
Xbcabc defdef Xbcabc
$ echo ${arr[@]//a/X} # Replace all 'a' in each element
XbcXbc defdef XbcXbc
$ echo ${arr[@]/?/X} # Replace first character in each element
Xbcabc Xefdef Xbcabc
$ echo ${arr[@]//?/X} # Replace all characters in all elements
XXXXXX XXXXXX XXXXXX
组合
这些也可以合并:
$ arr=(patxxx xxpatxx xxxpat) # Create array
$ echo ${arr[@]/pat/X} # Replace 'pat' in each element
Xxxx xxXxx xxxX
$ echo ${arr[@]/%pat/X} # Replace 'pat' if it matches at the end
patxxx xxpatxx xxxX
$ echo ${arr[@]/#pat/X} # Replace 'pat' if it matches at the beginning
Xxxx xxpatxx xxxpat
扩展模式匹配
与extended patterns一起,搜索和替换的参数扩展变得非常强大:
$ printf -v var "%b" ' have_spaces\t' # Has space and tab
$ echo "$var" | cat -A # Show whitespace
have_spaces^I$
$ shopt -s extglob # Turn on extended pattern matching
$ echo "${var//+([[:space:]])}" | cat -A # Remove all whitespace
have_spaces$
这个例子有点做作,因为同样的问题可以更简单地解决 - 重点是它非常灵活。