bash中有没有将字符串转换为小写字符串的方法?
例如,如果我有:
a="Hi all"
我想将其转换为:
"hi all"
bash中有没有将字符串转换为小写字符串的方法?
例如,如果我有:
a="Hi all"
我想将其转换为:
"hi all"
当前回答
对于Bash命令行,根据语言环境和国际字母,这可能会起作用(根据其他人的答案组合而成):
$ echo "ABCÆØÅ" | python -c "print(open(0).read().lower())"
abcæøå
$ echo "ABCÆØÅ" | sed 's/./\L&/g'
abcæøå
$ export a="ABCÆØÅ" | echo "${a,,}"
abcæøå
尽管这些变化可能不起作用:
$ echo "ABCÆØÅ" | tr "[:upper:]" "[:lower:]"
abcÆØÅ
$ echo "ABCÆØÅ" | awk '{print tolower($1)}'
abcÆØÅ
$ echo "ABCÆØÅ" | perl -ne 'print lc'
abcÆØÅ
$ echo 'ABCÆØÅ' | dd conv=lcase 2> /dev/null
abcÆØÅ
其他回答
你可以试试这个
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/
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
尽管这个问题有多古老,而且与技术龙的答案相似。我很难找到一个能够跨大多数平台(我使用的平台)以及旧版本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}}"
在zsh中:
echo $a:u
我爱你!
这是JaredTS486方法的一个更快的变体,该方法使用本地Bash功能(包括Bash版本<4.0)来优化他的方法。
我已经为一个小字符串(25个字符)和一个大字符串(445个字符)计时了1000次这种方法的迭代,无论是小写还是大写转换。由于测试字符串主要是小写,所以转换为小写通常比转换为大写更快。
我已经将我的方法与本页上与Bash 3.2兼容的其他几个答案进行了比较。我的方法比这里记录的大多数方法性能更高,在某些情况下甚至比tr更快。
以下是25个字符的1000次迭代的计时结果:
0.46s表示我的小写方式;大写0.96s奥韦洛菲的小写方法为1.16秒;大写字母为1.59tr转小写为3.67s;大写3.81s11.12s用于ghostdog74的小写方法;大写31.41秒26.25秒用于技术龙的小写方式;大写字母为26.21sJaredTS486的小写方法为25.06s;大写27.04s
445个字符的1000次迭代的计时结果(包括威特·拜纳的诗歌《罗宾》):
我的小写方法是2s;大写字母为12s4s表示tr为小写;大写字母为4s奥韦洛菲(Orwellophile)的小写方法为20秒;大写字母为29sghostdog74的小写方式为75秒;669表示大写。值得注意的是,在比赛占优势的测试和失误占优势的考试之间,表现差异有多大467秒表示技术龙的小写方式;大写字母为449660秒用于JaredTS486的小写方法;大写为660s。有趣的是,这种方法在Bash中产生了连续的页面错误(内存交换)
解决方案:
#!/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}"
}
方法很简单:当输入字符串中有剩余的大写字母时,找到下一个,并用其小写变体替换该字母的所有实例。重复此操作,直到替换所有大写字母。
我的解决方案的一些性能特点:
仅使用shell内置实用程序,这避免了在新进程中调用外部二进制实用程序的开销避免子壳,这会导致性能损失使用针对性能进行编译和优化的shell机制,例如变量内的全局字符串替换、变量后缀修剪以及正则表达式搜索和匹配。这些机制比手动遍历字符串快得多仅循环要转换的唯一匹配字符计数所需的次数。例如,将具有三个不同大写字符的字符串转换为小写只需要3次循环迭代。对于预配置的ASCII字母表,循环迭代的最大次数为26UCS和LCS可以添加其他字符