Answers:
有多种方式:
$ 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“]]奇怪地匹配[bz]内的情况,但[AZ]错误地匹配了[bz]。Bash被双负数(“ uncasematch”)弄糊涂了!:-)
word="Hi All"
像其他示例一样进行操作,则返回ha
,而不是hi all
。它仅适用于大写字母,并跳过已经小写的字母。
tr
和awk
示例。
tr '[:upper:]' '[:lower:]'
将使用当前语言环境来确定大写/小写字母的等效项,因此它将与使用带有变音符号的字母的语言环境一起使用。
b="$(echo $a | tr '[A-Z]' '[a-z]')"
在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
选项更改变量的属性,而不是内容。我的示例中的重新分配更新了内容以显示更改。
编辑:
${var~}
根据ghostdog74的建议,添加了“按单词切换第一个字符”()。
编辑:更正了波浪号行为,以匹配Bash 4.3。
string="łódź"; echo ${string~~}
将返回“ŁÓDŹ”,但echo ${string^^}
返回“łóDź”。即使在LC_ALL=pl_PL.utf-8
。那是使用bash 4.2.24。
en_US.UTF-8
。这是一个错误,我已经报告了。
echo "$string" | tr '[:lower:]' '[:upper:]'
。它可能会显示相同的故障。因此,问题至少部分不是Bash的问题。
echo "Hi All" | tr "[:upper:]" "[:lower:]"
tr
不适用于非ACII字符。我确实有正确的语言环境设置和生成的语言环境文件。有什么想法我会做错什么吗?
[:upper:]
需要?
a="$(tr [A-Z] [a-z] <<< "$a")"
{ print tolower($0) }
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
a="$(tr [A-Z] [a-z] <<< "$a")"
对我来说似乎最简单。我仍然是初学者...
sed
解决方案;我一直在一个由于某种原因而没有的环境中工作,tr
但是我还没有找到一个没有的系统sed
,加上很多时间我想这样做,sed
所以无论如何我还是做了其他事情,因此可以命令一起成为一个(长)语句。
tr [A-Z] [a-z] A
,如果存在由单个字母或nullgob组成的文件名,则Shell可以执行文件名扩展。tr "[A-Z]" "[a-z]" A
将表现正常。
sed
tr [A-Z] [a-z]
在几乎所有语言环境中这都是不正确的。例如,在en-US
语言环境中,A-Z
实际上是interval AaBbCcDdEeFfGgHh...XxYyZ
。
我知道这是一篇过时的文章,但是我在另一个网站上做了这个答案,所以我认为应该在这里发布:
上->下:使用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`
另外,当您说“外壳”时,我假设您的意思是,bash
但如果可以使用,zsh
它就像
b=$a:l
小写字母和
b=$a:u
大写。
a
包含单引号,则不仅行为不当,而且存在严重的安全问题。
在zsh中:
echo $a:u
一定爱zsh!
echo ${(C)a} #Upcase the first char only
对于仅使用内置函数的标准外壳程序(没有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}"
}
${var:1:1}
是Bashism。
你可以试试这个
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/
我想赞扬我希望分享的命令,但事实是我从http://commandlinefu.com获得了供我自己使用的命令。它的优点是,如果您cd
进入自己的主文件夹中的任何目录,它将递归地将所有文件和文件夹更改为小写,请谨慎使用。这是一个出色的命令行修复程序,对于已存储在驱动器中的大量相册特别有用。
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
您可以在查找后指定一个目录来代替点(。),它表示当前目录或完整路径。
我希望该解决方案证明是有用的,该命令不做的一件事就是用下划线替换空格-哦,也许还有一次。
prename
来自perl
:dpkg -S "$(readlink -e /usr/bin/rename)"
给perl: /usr/bin/prename
许多答案是使用外部程序,实际上并没有使用 Bash
。
如果您知道可以使用Bash4,则应该只使用 ${VAR,,}
符号(既简单又酷)。对于4之前的Bash(例如,我的Mac仍使用Bash 3.2)。我使用了@ ghostdog74的答案的更正版本来创建更可移植的版本。
您可以致电lowercase 'my STRING'
并获得小写版本。我读了有关将结果设置为var的注释,但这并不是真正可移植的Bash
,因为我们无法返回字符串。打印是最好的解决方案。容易被类似的东西捕获var="$(lowercase $str)"
。
如何运作
这种方法的工作方式是,先获取每个字符的ASCII整数表示形式,printf
然后使用adding 32
if upper-to->lower
或subtracting 32
if 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选项。
仅对字母进行大小写转换。因此,这应该工作整齐。
我专注于将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
如果使用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" )
${!1//\'/"'\''"}
代替也${!1}
可以使之工作。对于低于4.0的Bash版本,此版本应该是最快的(因为它不会派生/执行任何命令):
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"
}
尽管技工龙的答案确实适合我,但它也有潜力。
尽管这个问题有几岁了,而且与科技恐龙的答案相似。我很难找到一个可以在大多数平台(我使用的平台)以及较旧版本的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}" ]] ; then
input="${input/${input:$i:1}/${ucs:$j:1}}"
fi
done
done
简单的C风格的for循环遍历字符串。对于下面的行,如果您在我学到这之前没有看到 过这样的内容。在这种情况下,该行检查输入中是否存在char $ {input:$ i:1}(小写),如果存在,将其替换为给定的char $ {ucs:$ j:1}(大写)并存储它返回输入。
input="${input/${input:$i:1}/${ucs:$j:1}}"
这是JaredTS486使用本地Bash功能(包括低于4.0的Bash版本)来优化其方法的方法的更快变化。
我已经为小字符串(25个字符)和大字符串(445个字符)定时了1000次此方法的迭代,无论是小写还是大写转换。由于测试字符串主要是小写字母,因此转换为小写字母通常比转换为大写字母更快。
我已经将我的方法与本页上其他与Bash 3.2兼容的答案进行了比较。我的方法比此处记录的大多数方法具有更高的性能,甚至比tr
在几种情况下还快。
以下是25个字符的1,000次迭代的计时结果:
tr
小写字母为3.67秒;大写3.81秒445个字符的1,000次迭代的计时结果(由Witter Bynner的诗歌“ The Robin”组成):
tr
小写;大写字母4s解:
#!/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
可以增加其他字符