答案 0 :(得分:1857)
有多种方式:
$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all
$ echo "$a" | awk '{print tolower($0)}'
hi all
使用以下示例可能会遇到可移植性问题:
$ echo "${a,,}"
hi all
$ echo "$a" | sed -e 's/\(.*\)/\L\1/'
hi all
# this also works:
$ sed -e 's/\(.*\)/\L\1/' <<< "$a"
hi all
$ echo "$a" | perl -ne 'print lc'
hi all
lc(){
case "$1" in
[A-Z])
n=$(printf "%d" "'$1")
n=$((n+32))
printf \\$(printf "%o" "$n")
;;
*)
printf "%s" "$1"
;;
esac
}
word="I Love Bash"
for((i=0;i<${#word};i++))
do
ch="${word:$i:1}"
lc "$ch"
done
注意:YMMV就此而言。对我来说不起作用(GNU bash版本4.2.46和4.0.33(以及相同的行为2.05b.0但未实现nocasematch))即使使用shopt -u nocasematch;
也是如此。取消设置nocasematch导致[[“fooBaR”==“FOObar”]]匹配OK BUT内部奇怪地[b-z]被[A-Z]错误地匹配。 Bash被双阴性(“未设置的nocasematch”)弄糊涂了! : - )
答案 1 :(得分:393)
在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
要关闭declare
属性,请使用+
。例如,declare +c string
。这会影响后续分配,而不会影响当前值。
declare
选项更改变量的属性,但不更改内容。我的示例中的重新分配更新了内容以显示更改。
修改强>
按 ghostdog74 的建议添加“按字首字母切换”(${var~}
)。
编辑:更正了波形符合行为以匹配Bash 4.3。
答案 2 :(得分:117)
echo "Hi All" | tr "[:upper:]" "[:lower:]"
答案 3 :(得分:74)
a="$(tr [A-Z] [a-z] <<< "$a")"
{ print tolower($0) }
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
答案 4 :(得分:41)
我知道这是一个古老的帖子,但我为另一个网站做了这个答案,所以我想我会把它发布在这里:
UPPER - &gt;下强>: 使用python:
b=`echo "print '$a'.lower()" | python`
或Ruby:
b=`echo "print '$a'.downcase" | ruby`
或Perl(可能是我最喜欢的):
b=`perl -e "print lc('$a');"`
或PHP:
b=`php -r "print strtolower('$a');"`
或者Awk:
b=`echo "$a" | awk '{ print tolower($1) }'`
或Sed:
b=`echo "$a" | sed 's/./\L&/g'`
或Bash 4:
b=${a,,}
如果你有NodeJS(并且有点疯狂......):
b=`echo "console.log('$a'.toLowerCase());" | node`
您也可以使用dd
(但我不会!):
b=`echo "$a" | dd conv=lcase 2> /dev/null`
更低 - &gt; UPPER 强>:
使用python:
b=`echo "print '$a'.upper()" | python`
或Ruby:
b=`echo "print '$a'.upcase" | ruby`
或Perl(可能是我最喜欢的):
b=`perl -e "print uc('$a');"`
或PHP:
b=`php -r "print strtoupper('$a');"`
或者Awk:
b=`echo "$a" | awk '{ print toupper($1) }'`
或Sed:
b=`echo "$a" | sed 's/./\U&/g'`
或Bash 4:
b=${a^^}
如果你有NodeJS(并且有点疯狂......):
b=`echo "console.log('$a'.toUpperCase());" | node`
您也可以使用dd
(但我不会!):
b=`echo "$a" | dd conv=ucase 2> /dev/null`
另外当你说“贝壳”时我假设您的意思是bash
,但如果您可以使用zsh
,那就像
b=$a:l
小写和
b=$a:u
表示大写。
答案 5 :(得分:28)
在zsh中:
echo $a:u
得爱zsh!
答案 6 :(得分:17)
使用GNU sed
:
sed 's/.*/\L&/'
示例:
$ foo="Some STRIng";
$ foo=$(echo "$foo" | sed 's/.*/\L&/')
$ echo "$foo"
some string
答案 7 :(得分:11)
Pre Bash 4.0
Bash降低字符串的大小写并分配给变量
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"
答案 8 :(得分:11)
对于仅使用内置函数的标准shell(没有bashisms):
uppers=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lowers=abcdefghijklmnopqrstuvwxyz
lc(){ #usage: lc "SOME STRING" -> "some string"
i=0
while ([ $i -lt ${#1} ]) do
CUR=${1:$i:1}
case $uppers in
*$CUR*)CUR=${uppers%$CUR*};OUTPUT="${OUTPUT}${lowers:${#CUR}:1}";;
*)OUTPUT="${OUTPUT}$CUR";;
esac
i=$((i+1))
done
echo "${OUTPUT}"
}
对于大写:
uc(){ #usage: uc "some string" -> "SOME STRING"
i=0
while ([ $i -lt ${#1} ]) do
CUR=${1:$i:1}
case $lowers in
*$CUR*)CUR=${lowers%$CUR*};OUTPUT="${OUTPUT}${uppers:${#CUR}:1}";;
*)OUTPUT="${OUTPUT}$CUR";;
esac
i=$((i+1))
done
echo "${OUTPUT}"
}
答案 9 :(得分:8)
在bash 4中你可以使用排版
示例:
A="HELLO WORLD"
typeset -l A=$A
答案 10 :(得分:7)
我想赞扬我希望分享的命令,但事实是我从http://commandlinefu.com获得了我自己使用的命令。它的优点是,如果您cd
到您自己的主文件夹中的任何目录,它将以递归方式将所有文件和文件夹更改为小写,请谨慎使用。这是一个出色的命令行修复,对于存储在驱动器上的大量专辑特别有用。
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
您可以在find之后指定一个目录来代替点(。),表示当前目录或完整路径。
我希望这个解决方案证明有用,这个命令没有做的一件事是用下划线替换空格 - 哦,也许是另一个时间。
答案 11 :(得分:7)
你可以试试这个
s="Hello World!"
echo $s # Hello World!
a=${s,,}
echo $a # hello world!
b=${s^^}
echo $b # HELLO WORLD!
参考:http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/
答案 12 :(得分:3)
如果使用v4,则为baked-in。如果没有,这是一个简单,广泛适用的解决方案。这个帖子的其他答案(和评论)在创建下面的代码时非常有帮助。
# Like echo, but converts to lowercase
echolcase () {
tr [:upper:] [:lower:] <<< "${*}"
}
# Takes one arg by reference (var name) and makes it lowercase
lcase () {
eval "${1}"=\'$(echo ${!1//\'/"'\''"} | tr [:upper:] [:lower:] )\'
}
注意:
a="Hi All"
然后:lcase a
将执行以下操作:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
代替${!1}
也可以使用它。答案 13 :(得分:3)
对于早于4.0的Bash版本,此版本应该是最快的(因为它没有fork/exec任何命令):
function string.monolithic.tolower
{
local __word=$1
local __len=${#__word}
local __char
local __octal
local __decimal
local __result
for (( i=0; i<__len; i++ ))
do
__char=${__word:$i:1}
case "$__char" in
[A-Z] )
printf -v __decimal '%d' "'$__char"
printf -v __octal '%03o' $(( $__decimal ^ 0x20 ))
printf -v __char \\$__octal
;;
esac
__result+="$__char"
done
REPLY="$__result"
}
technosaurus's answer也有潜力,虽然它确实适合我。
答案 14 :(得分:3)
尽管这个问题多久了,但与this answer by technosaurus类似。我很难找到一个可以在大多数平台(我使用的)以及旧版本的bash上移植的解决方案。我也对数组,函数以及打印,回声和临时文件的使用感到沮丧,以检索琐碎的变量。到目前为止,这对我来说非常有效,我想我会分享。 我的主要测试环境是:
- GNU bash,版本4.1.2(1)-release(x86_64-redhat-linux-gnu)
- GNU bash,版本3.2.57(1)-release(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-style for loop来遍历字符串。 对于下面的行,如果你之前没有见过这样的话 this is where I learned this。在这种情况下,行检查输入中是否存在char $ {input:$ i:1}(小写),如果是,则用给定的char $ {ucs:$ j:1}(大写)替换它并存储它回到输入。
input="${input/${input:$i:1}/${ucs:$j:1}}"
答案 15 :(得分:3)
使用外部程序的许多答案,实际上并没有使用Bash
。
如果您知道Bash4可用,那么您应该使用${VAR,,}
符号(这很简单,很酷)。对于4之前的Bash(我的Mac仍然使用Bash 3.2)。我使用@ ghostdog74的修正版本的答案来创建一个更便携的版本。
您可以拨打lowercase 'my STRING'
并获得小写版本。我读到了关于将结果设置为var的注释,但在Bash
中这并不是真正可移植的,因为我们无法返回字符串。打印它是最好的解决方案。使用var="$(lowercase $str)"
等内容轻松捕捉。
如何运作
这种方法的工作方式是使用printf
获取每个字符的ASCII整数表示,然后adding 32
获取upper-to->lower
,或subtracting 32
获取lower-to->upper
。然后再次使用printf
将数字转换回char。从'A' -to-> 'a'
我们得到32个字符的差异。
使用printf
解释:
$ printf "%d\n" "'a"
97
$ printf "%d\n" "'A"
65
97 - 65 = 32
这是带有例子的工作版本 请注意代码中的注释,因为它们解释了很多内容:
#!/bin/bash
# lowerupper.sh
# Prints the lowercase version of a char
lowercaseChar(){
case "$1" in
[A-Z])
n=$(printf "%d" "'$1")
n=$((n+32))
printf \\$(printf "%o" "$n")
;;
*)
printf "%s" "$1"
;;
esac
}
# Prints the lowercase version of a sequence of strings
lowercase() {
word="$@"
for((i=0;i<${#word};i++)); do
ch="${word:$i:1}"
lowercaseChar "$ch"
done
}
# Prints the uppercase version of a char
uppercaseChar(){
case "$1" in
[a-z])
n=$(printf "%d" "'$1")
n=$((n-32))
printf \\$(printf "%o" "$n")
;;
*)
printf "%s" "$1"
;;
esac
}
# Prints the uppercase version of a sequence of strings
uppercase() {
word="$@"
for((i=0;i<${#word};i++)); do
ch="${word:$i:1}"
uppercaseChar "$ch"
done
}
# The functions will not add a new line, so use echo or
# append it if you want a new line after printing
# Printing stuff directly
lowercase "I AM the Walrus!"$'\n'
uppercase "I AM the Walrus!"$'\n'
echo "----------"
# Printing a var
str="A StRing WITH mixed sTUFF!"
lowercase "$str"$'\n'
uppercase "$str"$'\n'
echo "----------"
# Not quoting the var should also work,
# since we use "$@" inside the functions
lowercase $str$'\n'
uppercase $str$'\n'
echo "----------"
# Assigning to a var
myLowerVar="$(lowercase $str)"
myUpperVar="$(uppercase $str)"
echo "myLowerVar: $myLowerVar"
echo "myUpperVar: $myUpperVar"
echo "----------"
# You can even do stuff like
if [[ 'option 2' = "$(lowercase 'OPTION 2')" ]]; then
echo "Fine! All the same!"
else
echo "Ops! Not the same!"
fi
exit 0
运行后的结果:
$ ./lowerupper.sh
i am the walrus!
I AM THE WALRUS!
----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!
----------
a string with mixed stuff!
A STRING WITH MIXED STUFF!
----------
myLowerVar: a string with mixed stuff!
myUpperVar: A STRING WITH MIXED STUFF!
----------
Fine! All the same!
这应仅适用于ASCII字符。
对我来说没关系,因为我知道我只会传递ASCII字符 我正在使用它来处理一些不区分大小写的CLI选项,例如。
答案 16 :(得分:2)
转换案例仅适用于字母。所以,这应该工作得很好。
我专注于将a-z之间的字母表从大写字母转换为小写字母。任何其他字符都应该在stdout中打印出来......
将a-z范围内的路径/中的所有文本转换为/ file / filename到A-Z
将小写转换为大写
cat path/to/file/filename | tr 'a-z' 'A-Z'
从大写转换为小写
cat path/to/file/filename | tr 'A-Z' 'a-z'
例如,
文件名:
my name is xyz
转换为:
MY NAME IS XYZ
示例2:
echo "my name is 123 karthik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 KARTHIK
示例3:
echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
答案 17 :(得分:2)
如果您喜欢python并可以选择安装新的python软件包,则可以尝试使用此python utility。
# install pythonp
$ pip install pythonp
$ echo $a | pythonp "l.lower()"
答案 18 :(得分:1)
这是JaredTS486's approach的更快变体,它使用本机Bash功能(包括Bash版本<4.0)来优化他的方法。
我已经为小字符串(25个字符)和大字符串(445个字符)定时了1000次此方法的迭代,无论是小写还是大写转换。由于测试字符串主要是小写字母,因此转换为小写字母通常比转换为大写字母更快。
我已将我的方法与本页上其他与Bash 3.2兼容的答案进行了比较。我的方法比此处记录的大多数方法具有更高的性能,在某些情况下甚至比tr
更快。
以下是25个字符的1,000次迭代的计时结果:
tr
的小写字母为1,000次迭代的445个字符的计时结果(由Witter Bynner的诗歌“ The Robin”组成):
tr
为解决方案:
#!/bin/bash
set -e
set -u
declare LCS="abcdefghijklmnopqrstuvwxyz"
declare UCS="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
function lcase()
{
local TARGET="${1-}"
local UCHAR=''
local UOFFSET=''
while [[ "${TARGET}" =~ ([A-Z]) ]]
do
UCHAR="${BASH_REMATCH[1]}"
UOFFSET="${UCS%%${UCHAR}*}"
TARGET="${TARGET//${UCHAR}/${LCS:${#UOFFSET}:1}}"
done
echo -n "${TARGET}"
}
function ucase()
{
local TARGET="${1-}"
local LCHAR=''
local LOFFSET=''
while [[ "${TARGET}" =~ ([a-z]) ]]
do
LCHAR="${BASH_REMATCH[1]}"
LOFFSET="${LCS%%${LCHAR}*}"
TARGET="${TARGET//${LCHAR}/${UCS:${#LOFFSET}:1}}"
done
echo -n "${TARGET}"
}
方法很简单:当输入字符串中存在任何剩余的大写字母时,找到下一个字母,然后用小写字母替换该字母的所有实例。重复直到所有大写字母都被替换。
我的解决方案的一些性能特征:
UCS
和LCS
可以增加其他字符答案 19 :(得分:0)
将转换后的字符串存储到变量中。以下为我工作 -
$SOURCE_NAME
至$TARGET_NAME
TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"
答案 20 :(得分:0)
简单方法
echo "Hi all" | awk '{ print tolower($0); }'
答案 21 :(得分:0)
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