bash中有一种方法可以将字符串转换为小写字符串?
例如,如果我有:
a="Hi all"
我想将其转换为:
"hi all"
#1楼
如果使用v4,则已烘焙 。 如果没有,这是一个简单的,广泛适用的解决方案。 此线程上的其他答案(和注释)对于创建下面的代码很有帮助。
# 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" )
- 在lcase函数中,使用
${!1//\\'/"'\\''"}
而不是${!1}
,即使在字符串带引号的情况下也可以使用。
#2楼
对于4.0之前的Bash版本,此版本应该是最快的(因为它不会派生/执行任何命令):
function string.monolithic.tolower
{local __word=$1local __len=${#__word}local __charlocal __octallocal __decimallocal __resultfor (( 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"doneREPLY="$__result"
}
尽管技工龙的答案确实适合我,但它也有潜力。
#3楼
在bash 4中,您可以使用排版
例:
A="HELLO WORLD"
typeset -l A=$A
#4楼
前Bash 4.0
Bash减小字符串的大小写并分配给变量
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]') echo "$VARIABLE"
#5楼
使用GNU sed
:
sed 's/.*/\L&/'
例:
$ foo="Some STRIng";
$ foo=$(echo "$foo" | sed 's/.*/\L&/')
$ echo "$foo"
some string
#6楼
tr :
a="$(tr [A-Z] [a-z] <<< "$a")"
AWK :
{ print tolower($0) }
sed :
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
#7楼
echo "Hi All" | tr "[:upper:]" "[:lower:]"
#8楼
有多种方式:
POSIX标准
TR
$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all
AWK
$ echo "$a" | awk '{print tolower($0)}'
hi all
非POSIX
您可能会遇到以下示例的可移植性问题:
重击4.0
$ echo "${a,,}"
hi all
sed
$ 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++))
doch="${word:$i:1}"lc "$ch"
done
注意:YMMV就此。 即使使用shopt -u nocasematch;
它也对我不起作用(GNU bash版本4.2.46和4.0.33(具有相同的行为2.05b.0,但未实现nocasematch)) shopt -u nocasematch;
。 取消设置nocasematch会导致[[“” fooBaR“ ==” FOObar“]]奇怪地匹配[Bz]内的情况,但[AZ]错误地匹配了[Bz]。 Bash被双负数(“ uncasematch”)弄糊涂了! :-)
#9楼
在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~}
var? ${var~}
)。
编辑:更正了波浪号行为,以匹配Bash 4.3。
#10楼
我知道这是一篇过时的文章,但是我在另一个网站上做了这个答案,所以我想把它张贴在这里:
上->下 :使用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'`
或重击4:
b=${a,,}
或NodeJS(如果有)(有点发疯...):
b=`echo "console.log('$a'.toLowerCase());" | node`
您也可以使用dd
(但我不会!):
b=`echo "$a" | dd conv=lcase 2> /dev/null`
下->上 :
使用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'`
或重击4:
b=${a^^}
或NodeJS(如果有)(有点发疯...):
b=`echo "console.log('$a'.toUpperCase());" | node`
您也可以使用dd
(但我不会!):
b=`echo "$a" | dd conv=ucase 2> /dev/null`
另外,当您说“ shell”时,我假设您的意思是bash
但是如果可以使用zsh
它就像
b=$a:l
小写字母和
b=$a:u
大写。
#11楼
尽管这个问题有几岁了,而且与科技恐龙的答案相似 。 我很难找到一个可以在大多数平台(我使用的平台)以及较旧版本的bash上移植的解决方案。 我也对数组,函数以及使用打印,回显和临时文件来检索琐碎的变量感到沮丧。 到目前为止,这对我来说非常有效,我以为我会分享。 我的主要测试环境是:
- GNU bash版本4.1.2(1)-发行版(x86_64-redhat-linux-gnu)
- GNU bash版本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}" ]] ; theninput="${input/${input:$i:1}/${ucs:$j:1}}" fidone
done
简单的C风格的for循环遍历字符串。 对于下面的行,如果您在我学到这之前没有看到过这样的内容 。 在这种情况下,该行检查输入中是否存在char $ {input:$ i:1}(小写),如果存在,将其替换为给定的char $ {ucs:$ j:1}(大写)并存储它返回输入。
input="${input/${input:$i:1}/${ucs:$j:1}}"
#12楼
将转换后的字符串存储到变量中。 以下项目对我$TARGET_NAME
- $SOURCE_NAME
至$TARGET_NAME
TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"
#13楼
你可以试试这个
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/
#14楼
许多答案是使用外部程序的,而实际上不是使用Bash
。
如果您知道可以使用Bash4,则应该只使用${VAR,,}
表示法(既简单又酷)。 对于4之前的Bash(例如,我的Mac仍使用Bash 3.2)。 我使用了@ ghostdog74的答案的更正版本来创建更可移植的版本。
您可以将lowercase 'my STRING'
称为lowercase 'my STRING'
并获得小写字母的版本。 我读过有关将结果设置为var的注释,但这在Bash
并不是真正可移植的,因为我们无法返回字符串。 打印是最好的解决方案。 易于使用var="$(lowercase $str)"
捕获。
如何运作
这种工作方式是通过获取与每个字符的ASCII整数表示printf
然后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++)); doch="${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++)); doch="${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')" ]]; thenecho "Fine! All the same!"
elseecho "Ops! Not the same!"
fiexit 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选项。
#15楼
正则表达式
我想赞扬我希望分享的命令,但事实是我从http://commandlinefu.com获得了供我自己使用的命令。 这样做的好处是,如果您cd
到自己的主文件夹中的任何目录,它将以递归方式将所有文件和文件夹更改为小写,请谨慎使用。 这是一个出色的命令行修复程序,对于您存储在驱动器上的大量专辑特别有用。
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
您可以在查找后指定一个目录来代替点(。),它表示当前目录或完整路径。
我希望该解决方案证明是有用的,此命令不做的一件事就是用下划线替换空格-哦,也许还有一次。
#16楼
在zsh中:
echo $a:u
一定爱zsh!
#17楼
仅对字母进行大小写转换。 因此,这应该工作整齐。
我专注于将az的字母从大写转换为小写。 其他任何字符都应该按原样打印在标准输出中...
将z范围内path / to / file / filename中的所有文本转换为AZ
用于将小写转换为大写
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
#18楼
这是JaredTS486使用本地Bash功能(包括低于4.0的Bash版本)来优化其方法的方法的更快变化。
我已经为小字符串(25个字符)和大字符串(445个字符)定时了1000次此方法的迭代,无论是小写还是大写转换。 由于测试字符串主要是小写字母,因此转换为小写字母通常比转换为大写字母更快。
我已经将我的方法与本页上其他与Bash 3.2兼容的答案进行了比较。 我的方法比此处记录的大多数方法具有更高的性能,在某些情况下甚至比tr
更快。
以下是25个字符的1,000次迭代的计时结果:
- 我的小写字母为0.46s; 大写为0.96s
- Orwellophile 的小写方法为1.16分 ; 大写1.59s
-
tr
至小写字母为3.67秒; 大写3.81秒 - ghostdog74 的小写方式为11.12秒 ; 大写31.41秒
- Technosaurus 处理小写字母的时间为26.25s ; 大写26.21秒
- JaredTS486 的小写方法为25.06秒 ; 大写27.04秒
445个字符的1,000次迭代的计时结果(由Witter Bynner的诗歌“ The Robin”组成):
- 我的小写方法为2秒; 大写字母12s
-
tr
小写为4s; 大写字母4s - Orwellophile的小写方法为20 秒 ; 大写字母29s
- ghostdog74 的小写方式为75s ; 大写为669s。 有趣的是,在比赛占优势的测试与失误占优势的测试之间,性能差异有多大
- techsausaurus的小写字母为467秒 ; 大写449s
- JaredTS486 的小写方法为660s ; 大写660s。 有趣的是,这种方法在Bash中产生了连续的页面错误(内存交换)
解:
#!/bin/bash
set -e
set -udeclare LCS="abcdefghijklmnopqrstuvwxyz"
declare UCS="ABCDEFGHIJKLMNOPQRSTUVWXYZ"function lcase()
{local TARGET="${1-}"local UCHAR=''local UOFFSET=''while [[ "${TARGET}" =~ ([A-Z]) ]]doUCHAR="${BASH_REMATCH[1]}"UOFFSET="${UCS%%${UCHAR}*}"TARGET="${TARGET//${UCHAR}/${LCS:${#UOFFSET}:1}}"doneecho -n "${TARGET}"
}function ucase()
{local TARGET="${1-}"local LCHAR=''local LOFFSET=''while [[ "${TARGET}" =~ ([a-z]) ]]doLCHAR="${BASH_REMATCH[1]}"LOFFSET="${LCS%%${LCHAR}*}"TARGET="${TARGET//${LCHAR}/${UCS:${#LOFFSET}:1}}"doneecho -n "${TARGET}"
}
这种方法很简单:当输入字符串中存在所有剩余的大写字母时,找到下一个字母,然后用小写字母替换该字母的所有实例。 重复直到所有大写字母都被替换。
我的解决方案的一些性能特征:
- 仅使用shell内置实用程序,从而避免了在新进程中调用外部二进制实用程序的开销
- 避免使用子壳,否则会导致性能下降
- 使用针对性能进行编译和优化的外壳程序机制,例如变量内的全局字符串替换,变量后缀修整以及正则表达式搜索和匹配。 这些机制比通过字符串手动迭代要快得多
- 仅循环计数要转换的唯一匹配字符数所需的次数。 例如,将具有三个不同大写字符的字符串转换为小写仅需要3次循环迭代。 对于预配置的ASCII字母,最大循环迭代次数为26
-
UCS
和LCS
可以增加其他字符
#19楼
如果您喜欢python并且可以选择安装新的python软件包,则可以尝试使用此python实用工具 。
# install pythonp
$ pip install pythonp$ echo $a | pythonp "l.lower()"
#20楼
简单的方法
echo "Hi all" | awk '{ print tolower($0); }'
#21楼
对于仅使用内置函数的标准外壳程序(没有bashisms):
uppers=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lowers=abcdefghijklmnopqrstuvwxyzlc(){ #usage: lc "SOME STRING" -> "some string"i=0while ([ $i -lt ${#1} ]) doCUR=${1:$i:1}case $uppers in*$CUR*)CUR=${uppers%$CUR*};OUTPUT="${OUTPUT}${lowers:${#CUR}:1}";;*)OUTPUT="${OUTPUT}$CUR";;esaci=$((i+1))doneecho "${OUTPUT}"
}
对于大写:
uc(){ #usage: uc "some string" -> "SOME STRING"i=0while ([ $i -lt ${#1} ]) doCUR=${1:$i:1}case $lowers in*$CUR*)CUR=${lowers%$CUR*};OUTPUT="${OUTPUT}${uppers:${#CUR}:1}";;*)OUTPUT="${OUTPUT}$CUR";;esaci=$((i+1))doneecho "${OUTPUT}"
}