如何在 Bash 中嵌套用于大写和替换的参数扩展?
How do I nest parameter expansions for uppercasing and substitution in Bash?
我有两个 bash 字符串内置命令,它们独立运行良好,但无论我尝试什么,嵌套时都会生成错误消息。这是两个有效的命令:
$ A="etc/.java"
$ echo $A
/etc/.java
$ B="${A//$'76'/$'7'}"
$ echo $B
/etc/java
$ B="${A^^}"
$ echo $B
/ETC/.JAVA
现在尝试将这两个命令组合在一起时出现错误:
$ B="${${A^^}//$'76'/$'7'}"
bash: ${${A^^}///.//}: bad substitution
$ B="${ ${A^^}//$'76'/$'7'}"
bash: ${ ${A^^}///.//}: bad substitution
$ B="${ ${A^^} //$'76'/$'7'}"
bash: ${ ${A^^} ///.//}: bad substitution
$ B="${"${A^^}"//$'76'/$'7'}"
bash: ${"${A^^}"//'/.'/'/'}: bad substitution
$ B="${ "${A^^}" //$'76'/$'7'}"
bash: ${ "${A^^}" //'/.'/'/'}: bad substitution
$ B="${${A^^} //$'76'/$'7'}"
bash: ${${A^^} ///.//}: bad substitution
上面提供了简化示例,因此您可以复制并粘贴到自己的终端。管道或重定向会很复杂,因为我的真实代码是这样的:
while [[ $i -lt $DirsArrCnt ]] ; do
DirsArr[$i]=false
CurrNdx=$i
CurrKey="${DirsArr[$(( $i + 1 ))]}"
# ^^ = convert to upper-case
# ${Variable//$'16'/$'1'} = Change /. to / for hidden directory sorting
if [[ "${"${CurrKey^^}"//$'16'/$'1'}" > \
"${"${LastKey^^}"//$'16'/$'1'}" ]] || \
[[ "${"${CurrKey^^}"//$'16'/$'1'}" = \
"${"${LastKey^^}"//$'16'/$'1'}" ]] ; then
LastNdx=$CurrNdx
LastKey="$CurrKey"
i=$(( $i + $OneDirArrCnt))
continue
fi
在其中一个扩展是上壳的特殊情况下,可以使用 declare -u
(在 Bash 4.0 中引入)在单个扩展中完成。 declare -u
在赋值时转换为大写。
结合大写和替换就变成了这样:
$ declare -u A='/etc/.java'
$ echo "${A//\/./\/}"
/ETC/JAVA
对于小写字母有类似的 -l
和对于标题大小写的(未记录的)-c
,但这些是您可以进行 "nested" 参数扩展的唯一情况。
我有两个 bash 字符串内置命令,它们独立运行良好,但无论我尝试什么,嵌套时都会生成错误消息。这是两个有效的命令:
$ A="etc/.java"
$ echo $A
/etc/.java
$ B="${A//$'76'/$'7'}"
$ echo $B
/etc/java
$ B="${A^^}"
$ echo $B
/ETC/.JAVA
现在尝试将这两个命令组合在一起时出现错误:
$ B="${${A^^}//$'76'/$'7'}"
bash: ${${A^^}///.//}: bad substitution
$ B="${ ${A^^}//$'76'/$'7'}"
bash: ${ ${A^^}///.//}: bad substitution
$ B="${ ${A^^} //$'76'/$'7'}"
bash: ${ ${A^^} ///.//}: bad substitution
$ B="${"${A^^}"//$'76'/$'7'}"
bash: ${"${A^^}"//'/.'/'/'}: bad substitution
$ B="${ "${A^^}" //$'76'/$'7'}"
bash: ${ "${A^^}" //'/.'/'/'}: bad substitution
$ B="${${A^^} //$'76'/$'7'}"
bash: ${${A^^} ///.//}: bad substitution
上面提供了简化示例,因此您可以复制并粘贴到自己的终端。管道或重定向会很复杂,因为我的真实代码是这样的:
while [[ $i -lt $DirsArrCnt ]] ; do
DirsArr[$i]=false
CurrNdx=$i
CurrKey="${DirsArr[$(( $i + 1 ))]}"
# ^^ = convert to upper-case
# ${Variable//$'16'/$'1'} = Change /. to / for hidden directory sorting
if [[ "${"${CurrKey^^}"//$'16'/$'1'}" > \
"${"${LastKey^^}"//$'16'/$'1'}" ]] || \
[[ "${"${CurrKey^^}"//$'16'/$'1'}" = \
"${"${LastKey^^}"//$'16'/$'1'}" ]] ; then
LastNdx=$CurrNdx
LastKey="$CurrKey"
i=$(( $i + $OneDirArrCnt))
continue
fi
在其中一个扩展是上壳的特殊情况下,可以使用 declare -u
(在 Bash 4.0 中引入)在单个扩展中完成。 declare -u
在赋值时转换为大写。
结合大写和替换就变成了这样:
$ declare -u A='/etc/.java'
$ echo "${A//\/./\/}"
/ETC/JAVA
对于小写字母有类似的 -l
和对于标题大小写的(未记录的)-c
,但这些是您可以进行 "nested" 参数扩展的唯一情况。