bash中有没有将字符串转换为小写字符串的方法?
例如,如果我有:
a="Hi all"
我想将其转换为:
"hi all"
bash中有没有将字符串转换为小写字符串的方法?
例如,如果我有:
a="Hi all"
我想将其转换为:
"hi all"
当前回答
尽管这个问题有多古老,而且与技术龙的答案相似。我很难找到一个能够跨大多数平台(我使用的平台)以及旧版本bash移植的解决方案。我还对数组、函数以及使用prints、echo和临时文件来检索琐碎变量感到失望。到目前为止,这对我来说非常有效,我想我会分享。我的主要测试环境是:
GNUbash,版本4.1.2(1)-发布(x86_64-redhat-linux-GNU)GNUbash,版本3.2.57(1)-发布(sparc-sun-solaris2.10)
lcs="abcdefghijklmnopqrstuvwxyz"
ucs="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
input="Change Me To All Capitals"
for (( i=0; i<"${#input}"; i++ )) ; do :
for (( j=0; j<"${#lcs}"; j++ )) ; do :
if [[ "${input:$i:1}" == "${lcs:$j:1}" ]] ; then
input="${input/${input:$i:1}/${ucs:$j:1}}"
fi
done
done
循环的简单C样式,用于遍历字符串。如果您以前没有看到过类似的内容,请选择下面的行这是我学到的。在这种情况下,该行检查输入中是否存在字符${input:$i:1}(小写),如果存在,则用给定的字符${ucs:$j:1}(大写)替换它,并将其存储回输入中。
input="${input/${input:$i:1}/${ucs:$j:1}}"
其他回答
正则表达式
我想为我想分享的命令而感到自豪,但事实是我从http://commandlinefu.com.它的优点是,如果你cd到你自己的主文件夹中的任何目录,它会递归地将所有文件和文件夹更改为小写,请谨慎使用。这是一个出色的命令行修复程序,特别适用于您存储在驱动器上的大量相册。
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
您可以指定一个目录来代替查找后的点(.),该点表示当前目录或完整路径。
我希望这个解决方案证明是有用的,但这个命令不能做的一件事是用下划线替换空格-哦,也许下次吧。
基于Dejay Clayton出色的解决方案,我将大写/小写扩展为转置函数(独立有用),在变量中返回结果(更快/更安全),并添加了BASH v4+优化:
pkg::transpose() { # <retvar> <string> <from> <to>
local __r=$2 __m __p
while [[ ${__r} =~ ([$3]) ]]; do
__m="${BASH_REMATCH[1]}"; __p="${3%${__m}*}"
__r="${__r//${__m}/${4:${#__p}:1}}"
done
printf -v "$1" "%s" "${__r}"
}
pkg::lowercase() { # <retvar> <string>
if (( BASH_VERSINFO[0] >= 4 )); then
printf -v "$1" "%s" "${2,,}"
else
pkg::transpose "$1" "$2" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz"
fi
}
pkg::uppercase() { # <retvar> <string>
if (( BASH_VERSINFO[0] >= 4 )); then
printf -v "$1" "%s" "${2^^}"
else
pkg::transpose "$1" "$2" "abcdefghijklmnopqrstuvwxyz" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
fi
}
为了简单起见,我没有添加任何set-e支持(或任何错误检查)。。。但除此之外,它通常遵循shellguide和pkg::transpose()试图避免printf-v的任何可能的变量名冲突
在Bash 4中:
小写
$ string="A FEW WORDS"
$ echo "${string,}"
a FEW WORDS
$ echo "${string,,}"
a few words
$ echo "${string,,[AEIUO]}"
a FeW WoRDS
$ string="A Few Words"
$ declare -l string
$ string=$string; echo "$string"
a few words
大写
$ string="a few words"
$ echo "${string^}"
A few words
$ echo "${string^^}"
A FEW WORDS
$ echo "${string^^[aeiou]}"
A fEw wOrds
$ string="A Few Words"
$ declare -u string
$ string=$string; echo "$string"
A FEW WORDS
切换(未记录,但可在编译时配置)
$ string="A Few Words"
$ echo "${string~~}"
a fEW wORDS
$ string="A FEW WORDS"
$ echo "${string~}"
a FEW WORDS
$ string="a few words"
$ echo "${string~}"
A few words
大写(未记录,但可在编译时配置)
$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words
标题大小写:
$ string="a few words"
$ string=($string)
$ string="${string[@]^}"
$ echo "$string"
A Few Words
$ declare -c string
$ string=(a few words)
$ echo "${string[@]}"
A Few Words
$ string="a FeW WOrdS"
$ string=${string,,}
$ string=${string~}
$ echo "$string"
A few words
要关闭声明属性,请使用+。例如,声明+c字符串。这会影响后续赋值,而不是当前值。
declare选项更改变量的属性,但不更改内容。示例中的重新分配会更新内容以显示更改。
编辑:
按照ghostdog74的建议,添加了“按单词切换第一个字符”(${var~})。
编辑:更正波浪号行为以匹配Bash 4.3。
预冲击4.0
Bash降低字符串的大小写并赋值给变量
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"
Bash 5.1提供了一种通过L参数转换实现这一点的直接方法:
${var@L}
例如,你可以说:
v="heLLo"
echo "${v@L}"
# hello
也可以使用U大写:
v="hello"
echo "${v@U}"
# HELLO
第一个字母用u大写:
v="hello"
echo "${v@u}"
# Hello