如何在Bash中将字符串转换为小写

有没有办法在将字符串转换为小写字符串?

例如,如果我有:

a="Hi all"

我想将其转换为:

"hi all"
1279378 次浏览

孩子们

a="$(tr [A-Z] [a-z] <<< "$a")"

AWK

{ print tolower($0) }

ed

y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
echo "Hi All" | tr "[:upper:]" "[:lower:]"

有各种方法:

POSIX标准

tr

$ echo "$a" | tr '[:upper:]' '[:lower:]'hi all

AWK

$ echo "$a" | awk '{print tolower($0)}'hi all

非POSIX

通过以下示例,您可能会遇到可移植性问题:

Bash 4.0

$ echo "${a,,}"hi all

se

$ echo "$a" | sed -e 's/\(.*\)/\L\1/'hi all# this also works:$ sed -e 's/\(.*\)/\L\1/' <<< "$a"hi all

Perl

$ echo "$a" | perl -ne 'print lc'hi all

Bash

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没有实现)。取消设置nocasematch会导致[["foBaR"=="FOObar"]]匹配OK,但内部大小写奇怪的是[b-z]被[A-Z]错误匹配。Bash被双重否定(“取消设置nocasematch")! :-)

在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。

正则表达式

我想为我想分享的命令负责,但事实是我从http://commandlinefu.com获得它供我自己使用。它的优点是,如果您cd到您自己的主文件夹中的任何目录,它将所有文件和文件夹更改为小写递归,请谨慎使用。这是一个出色的命令行修复程序,对于您存储在驱动器上的大量相册特别有用。

find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

您可以指定一个目录来代替查找后的点(.),该点表示当前目录或完整路径。

我希望这个解决方案证明是有用的,这个命令没有做的一件事是用下划线替换空格-哦,也许下次吧。

在zsh中:

echo $a:u

要爱zsh!

对于仅使用内置函数的标准shell(没有bashism):

uppers=ABCDEFGHIJKLMNOPQRSTUVWXYZlowers=abcdefghijklmnopqrstuvwxyz
lc(){ #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}"}

如果使用v4,这是烘烤。如果不是,这是一个简单,广泛适用的解决方案。此线程上的其他答案(和注释)对创建下面的代码非常有帮助。

# Like echo, but converts to lowercaseecholcase () {tr [:upper:] [:lower:] <<< "${*}"}
# Takes one arg by reference (var name) and makes it lowercaselcase () {eval "${1}"=\'$(echo ${!1//\'/"'\''"} | tr [:upper:] [:lower:] )\'}

备注:

  • 执行:a="Hi All"然后:lcase a将执行与:a=$( echolcase "Hi All" )相同的操作
  • 在lcase函数中,使用${!1//\'/"'\''"}而不是${!1}允许它工作,即使字符串有引号。

对于4.0之前的Bash版本,这个版本应该是最快的(因为它没有forc/exec任何命令):

function string.monolithic.tolower{local __word=$1local __len=${#__word}local __charlocal __octallocal __decimallocal __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"doneREPLY="$__result"}

科技龙的答案也有潜力,尽管它确实适合mee。

在bash 4中,您可以使用排版

示例:

A="HELLO WORLD"typeset -l A=$A

preBash 4.0

Bash降低字符串的大小写并分配给变量

VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"

使用GNUsed

sed 's/.*/\L&/'

示例:

$ foo="Some STRIng";$ foo=$(echo "$foo" | sed 's/.*/\L&/')$ echo "$foo"some string

我知道这是一个古老的帖子,但我为另一个网站做了这个答案,所以我想我会在这里发布:

上->下:使用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=`node -p "\"$a\".toLowerCase()"`

你也可以使用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'`

Bash 4:

b=${a^^}

或者nodejs:

b=`node -p "\"$a\".toUpperCase()"`

你也可以使用dd

b=`echo "$a" | dd  conv=ucase 2> /dev/null`

此外,当你说'shell'时,我假设你的意思是bash,但如果你可以使用zsh,它就像

b=$a:l

对于小写和

b=$a:u

为大写。

尽管这个问题有多古老,并且与科技龙的回答相似。我很难找到一个可以在大多数平台(我使用的)以及旧版本的bash上移植的解决方案。我也对数组、函数和使用打印、回声和临时文件来检索琐碎的变量感到沮丧。到目前为止,这对我来说非常有效,我想我会分享。我的主要测试环境是:

  1. GNU bash,版本4.1.2(1)-发布(x86_64-redhat-linux-gnu)
  2. GNU bash,版本3.2.57(1)-发布(spac-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}}"fidonedone

简单C风格的for循环遍历字符串。对于下面的行,如果你以前没有见过这样的东西我就是在这里学到的。在这种情况下,该行检查char${输入:$i: 1}(小写)是否存在于输入中,如果存在,则将其替换为给定的char${ucs:$j: 1}(大写)并将其存储回输入中。

input="${input/${input:$i:1}/${ucs:$j:1}}"

将转换后的字符串存储为变量。以下对我有用-$SOURCE_NAME$TARGET_NAME

TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"

你可以试试这个

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

如果你知道你将有Bash4可用,你真的应该使用${VAR,,}符号(它既简单又酷)。对于4之前的Bash(例如我的Mac仍然使用Bash 3.2)。我使用了@ghostdog74答案的更正版本来创建一个更便携的版本。

你可以调用lowercase 'my STRING'并得到一个小写版本。我读了关于将结果设置为var的评论,但这在Bash中并不是真正的可移植,因为我们不能返回字符串。打印它是最好的解决方案。像var="$(lowercase $str)"这样的东西很容易捕获。

这是怎么运作的

其工作方式是通过printf获取每个char的ASCII整数表示,如果upper-to->lower,则为adding 32,如果lower-to->upper,则为subtracting 32。然后再次使用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 charlowercaseChar(){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 stringslowercase() {word="$@"for((i=0;i<${#word};i++)); doch="${word:$i:1}"lowercaseChar "$ch"done}
# Prints the uppercase version of a charuppercaseChar(){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 stringsuppercase() {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 directlylowercase "I AM the Walrus!"$'\n'uppercase "I AM the Walrus!"$'\n'
echo "----------"
# Printing a varstr="A StRing WITH mixed sTUFF!"lowercase "$str"$'\n'uppercase "$str"$'\n'
echo "----------"
# Not quoting the var should also work,# since we use "$@" inside the functionslowercase $str$'\n'uppercase $str$'\n'
echo "----------"
# Assigning to a varmyLowerVar="$(lowercase $str)"myUpperVar="$(uppercase $str)"echo "myLowerVar: $myLowerVar"echo "myUpperVar: $myUpperVar"
echo "----------"
# You can even do stuff likeif [[ 'option 2' = "$(lowercase 'OPTION 2')" ]]; thenecho "Fine! All the same!"elseecho "Ops! Not the same!"fi
exit 0

运行此操作后的结果:

$ ./lowerupper.shi 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选项。

转换大小写仅用于字母。所以,这应该可以整齐地工作。

我专注于将a-z之间的字母从大写转换为小写。任何其他字符都应该按原样打印在标准输出中…

将a-z范围内path/to/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

这是JaredTS486的方法的一个更快的变体,它使用本机Bash功能(包括Bash版本<4.0)来优化他的方法。

对于小写和大写转换,我已经为这种方法的1,000次迭代计时了一个小字符串(25个字符)和一个更大的字符串(445个字符)。由于测试字符串主要是小写的,因此转换为小写通常比大写快。

我已经将我的方法与本页上与Bash 3.2兼容的其他几个答案进行了比较。我的方法比这里记录的大多数方法性能更高,在某些情况下甚至比tr更快。

以下是25个字符的1,000次迭代的计时结果:

445个字符的1000次迭代的计时结果(包括Witter Bynner的诗“The Robin”):

  • 2s表示小写;12s表示大写
  • 4s表示tr为小写;4s表示大写
  • 亲奥威尔的方法转小写20秒;大写29秒
  • ghostdog74的方法为小写75秒;大写669秒。有趣的是,注意到具有主要匹配的测试与具有主要未命中的测试之间的性能差异是多么巨大
  • 科技龙进场到小写467秒;大写449秒
  • 660JaredTS486的方法为小写;660为大写。有趣的是,这种方法在Bash中产生了连续的页面错误(内存交换)

解决方案:

#!/bin/bashset -eset -u
declare 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}}"done
echo -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}}"done
echo -n "${TARGET}"}

方法很简单:当输入字符串存在任何剩余的大写字母时,找到下一个,并将该字母的所有实例替换为其小写变体。重复直到所有大写字母都被替换。

我的解决方案的一些性能特点:

  1. 仅使用shell内置实用程序,这避免了在新进程中调用外部二进制实用程序的开销
  2. 避免子shell,这会导致性能损失
  3. 使用针对性能进行编译和优化的shell机制,例如变量中的全局字符串替换、变量后缀修剪以及正则表达式搜索和匹配。这些机制远远快于手动遍历字符串
  4. 仅循环要转换的唯一匹配字符计数所需的次数。例如,将具有三个不同大写字符的字符串转换为小写只需要3次循环迭代。对于预配置的ASCII字母表,最大循环迭代次数为26次
  5. UCSLCS可以使用其他字符进行扩充

简单的方法

echo "Hi all" | awk '{ print tolower($0); }'

bash5.1提供了一种直接的方法来使用L参数转换来做到这一点:

${var@L}

例如,你可以说:

v="heLLo"echo "${v@L}"# hello

你也可以用U大写:

v="hello"echo "${v@U}"# HELLO

u大写第一个字母:

v="hello"echo "${v@u}"# Hello

基于DejayClayton优秀的解决方案,我将大写/小写泛化为转置函数(独立有用),将结果返回变量(更快/更安全),并添加了BASH v4+优化:

pkg::transpose() { # <retvar> <string> <from> <to>local __r=$2 __m __pwhile [[ ${__r} =~ ([$3]) ]]; do__m="${BASH_REMATCH[1]}"; __p="${3%${__m}*}"__r="${__r//${__m}/${4:${#__p}:1}}"doneprintf -v "$1" "%s" "${__r}"}pkg::lowercase() { # <retvar> <string>if (( BASH_VERSINFO[0] >= 4 )); thenprintf -v "$1" "%s" "${2,,}"elsepkg::transpose "$1" "$2" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \"abcdefghijklmnopqrstuvwxyz"fi}pkg::uppercase() { # <retvar> <string>if (( BASH_VERSINFO[0] >= 4 )); thenprintf -v "$1" "%s" "${2^^}"elsepkg::transpose "$1" "$2" "abcdefghijklmnopqrstuvwxyz" \"ABCDEFGHIJKLMNOPQRSTUVWXYZ"fi}

为了保持简单,我没有添加任何set-e支持(或任何错误检查)……但除此之外,它通常遵循导壳管pkg::transpose()试图避免printf -v的任何可能的变量名冲突

对于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/nullabcÆØÅ

bash手册页:

${参数^模式}

${参数^^模式}

${参数,模式}

${参数,,模式}

案例修改。此扩展修改了参数中字母字符的大小写。模式被扩展为生成一个与路径名扩展中的模式相同。展开后的每个字符参数的值与模式进行测试,如果匹配模式,其大小写被转换。模式不应尝试匹配多个字符。^运算符转换为小写将模式匹配为大写字母;,运算符转换为将大写字母与小写字母匹配。^^,,扩展转换扩展值中的每个匹配字符^,扩展匹配并仅转换扩展值中的第一个字符。如果省略模式,它将被视为?,匹配每个字符。如果参数@*,则依次对每个位置参数应用大小写修改操作,扩展为结果列表。如果参数是带有@*下标的数组变量,大小写修改操作应用于数组的每个成员转,展开是结果列表。

使用此命令执行相同的操作,它会将大写字符串转换为小写:

sed 's/[A-Z]/[a-z]/g' <filename>

所以我尝试使用共识方法为每个实用程序执行一些更新的基准测试,但不是重复一个小集合很多次,我…

  1. 送入#0#1文件,该文件以UTF-8编码填充到边缘w/多字节Unicode字符,
  2. 通过pipe来均衡I/O方面,
  3. 同时为所有人执行LC_ALL=C以确保公平竞争环境

————————————————————————————————————————

  • bsd-sedgnu-sed都相当平庸,说得好,非常

    • 我甚至不知道bsd-sed想做什么,因为他们的xxhash不匹配
  • python3试图做Unicode字母大小写吗?

    • (即使我已经强制语言环境设置LC_ALL=C
  • tr是最极端的

    1. gnu-tr是,到目前为止是最快的
    2. bsd-tr非常可怕
  • perl5比我拥有的任何awk变体都快,除非你可以使用mawk2一次加载整个文件,以便在perl5上获得一点点:

      2.935s mawk2vs3.081s perl5
  • awk中,gnu-gawk在3中最慢,mawk 1.3.4在中间,mawk 1.9.9.6最快:比gawk节省超过50%的时间

    .(我没有浪费我的时间与无用的#0)

.

     out9: 1.85GiB 0:00:03 [ 568MiB/s] [ 568MiB/s] [ <=> ]in0: 1.85GiB 0:00:03 [ 568MiB/s] [ 568MiB/s] [============>] 100%( pvE 0.1 in0 < "${m3t}" | LC_ALL=C mawk2 '{ print tolower($_) }' FS='^$'; )
mawk 1.9.9.6 (mawk2-beta)
3.07s user 0.66s system 111% cpu 3.348 total85759a34df874966d096c6529dbfb9d5  stdin

out9: 1.85GiB 0:00:06 [ 297MiB/s] [ 297MiB/s] [ <=> ]in0: 1.85GiB 0:00:06 [ 297MiB/s] [ 297MiB/s] [============>] 100%( pvE 0.1 in0 < "${m3t}" | LC_ALL=C mawk '{ print tolower($_) }' FS='^$'; )
mawk 1.3.4
6.01s user 0.83s system 107% cpu 6.368 total85759a34df874966d096c6529dbfb9d5  stdin
out9: 23.8MiB 0:00:00 [ 238MiB/s] [ 238MiB/s] [ <=> ]in0: 1.85GiB 0:00:07 [ 244MiB/s] [ 244MiB/s] [============>] 100%out9: 1.85GiB 0:00:07 [ 244MiB/s] [ 244MiB/s] [ <=>                             ]( pvE 0.1 in0 < "${m3t}" | LC_ALL=C gawk -be '{ print tolower($_) }' FS='^$';
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
7.49s user 0.78s system 106% cpu 7.763 total85759a34df874966d096c6529dbfb9d5  stdin

out9: 1.85GiB 0:00:03 [ 616MiB/s] [ 616MiB/s] [ <=> ]in0: 1.85GiB 0:00:03 [ 617MiB/s] [ 617MiB/s] [============>] 100%( pvE 0.1 in0 < "${m3t}" | LC_ALL=C perl -ne 'print lc'; )
perl5 (revision 5 version 34 subversion 0)
2.70s user 0.85s system 115% cpu 3.081 total85759a34df874966d096c6529dbfb9d5  stdin

out9: 1.85GiB 0:00:32 [57.4MiB/s] [57.4MiB/s] [ <=> ]in0: 1.85GiB 0:00:32 [57.4MiB/s] [57.4MiB/s] [============>] 100%( pvE 0.1 in0 < "${m3t}" | LC_ALL=C gsed 's/.*/\L&/'; )  # GNU-sed

gsed (GNU sed) 4.8
32.57s user 0.97s system 101% cpu 32.982 total85759a34df874966d096c6529dbfb9d5  stdin

out9: 1.86GiB 0:00:38 [49.7MiB/s] [49.7MiB/s] [ <=> ]in0: 1.85GiB 0:00:38 [49.4MiB/s] [49.4MiB/s] [============>] 100%( pvE 0.1 in0 < "${m3t}" | LC_ALL=C sed 's/.*/\L&/'; )   # BSD-sed


37.94s user 0.86s system 101% cpu 38.318 totald5e2d8487df1136db7c2334a238755c0  stdin


in0:  313MiB 0:00:00 [3.06GiB/s] [3.06GiB/s] [=====>] 16% ETA 0:00:00out9: 1.85GiB 0:00:11 [ 166MiB/s] [ 166MiB/s] [ <=>]in0: 1.85GiB 0:00:00 [3.31GiB/s] [3.31GiB/s] [============>] 100%( pvE 0.1 in0 < "${m3t}" | LC_ALL=C python3 -c "print(open(0).read().lower()))
Python 3.9.12
9.04s user 2.18s system 98% cpu 11.403 total7ddc0b5cbcfbbfac3c2b6da6731bd262  stdin
out9: 2.51MiB 0:00:00 [25.1MiB/s] [25.1MiB/s] [ <=> ]in0: 1.85GiB 0:00:11 [ 171MiB/s] [ 171MiB/s] [============>] 100%out9: 1.85GiB 0:00:11 [ 171MiB/s] [ 171MiB/s] [ <=> ]( pvE 0.1 in0 < "${m3t}" | LC_ALL=C ruby -pe '$_.downcase!'; )

ruby 2.6.8p205 (2021-07-07 revision 67951) [universal.arm64e-darwin21]
10.46s user 1.23s system 105% cpu 11.073 total85759a34df874966d096c6529dbfb9d5  stdin

in0: 1.85GiB 0:00:01 [1.01GiB/s] [1.01GiB/s] [============>] 100%out9: 1.85GiB 0:00:01 [1.01GiB/s] [1.01GiB/s] [ <=> ]( pvE 0.1 in0 < "${m3t}" | LC_ALL=C gtr '[A-Z]' '[a-z]'; )  # GNU-tr

gtr (GNU coreutils) 9.1
1.11s user 1.21s system 124% cpu 1.855 total85759a34df874966d096c6529dbfb9d5  stdin

out9: 1.85GiB 0:01:19 [23.7MiB/s] [23.7MiB/s] [ <=> ]in0: 1.85GiB 0:01:19 [23.7MiB/s] [23.7MiB/s] [============>] 100%( pvE 0.1 in0 < "${m3t}" | LC_ALL=C tr '[A-Z]' '[a-z]'; ) # BSD-tr
78.94s user 1.50s system 100% cpu 1:19.67 total85759a34df874966d096c6529dbfb9d5  stdin

( time ( pvE0 < "${m3t}" | LC_ALL=C   gdd  conv=lcase ) | pvE9 )  | xxh128sum | lgp3; sleep 3;out9: 0.00 B 0:00:01 [0.00 B/s] [0.00 B/s] [<=> ]in0: 1.85GiB 0:00:06 [ 295MiB/s] [ 295MiB/s] [============>] 100%out9: 1.81GiB 0:00:06 [ 392MiB/s] [ 294MiB/s] [ <=>   ]3874110+1 records in3874110+1 records outout9: 1.85GiB 0:00:06 [ 295MiB/s] [ 295MiB/s] [ <=>  ]( pvE 0.1 in0 < "${m3t}" | LC_ALL=C gdd conv=lcase; )  # GNU-dd

gdd (coreutils) 9.1
1.93s user 4.35s system 97% cpu 6.413 total85759a34df874966d096c6529dbfb9d5  stdin


%  ( time ( pvE0 < "${m3t}" | LC_ALL=C   dd  conv=lcase ) | pvE9 )  | xxh128sum | lgp3; sleep 3;out9: 36.9MiB 0:00:00 [ 368MiB/s] [ 368MiB/s] [ <=> ]in0: 1.85GiB 0:00:04 [ 393MiB/s] [ 393MiB/s] [============>] 100%out9: 1.85GiB 0:00:04 [ 393MiB/s] [ 393MiB/s] [ <=>   ]3874110+1 records in3874110+1 records outout9: 1.85GiB 0:00:04 [ 393MiB/s] [ 393MiB/s] [ <=>  ]( pvE 0.1 in0 < "${m3t}" | LC_ALL=C dd conv=lcase; )  # BSD-dd

1.92s user 4.24s system 127% cpu 4.817 total85759a34df874966d096c6529dbfb9d5  stdin

————————————————————————————————————————

通过一次性加载文件,并在单个函数调用中为所有1.85 GB执行tolower(),可以人为地使mawk2perl5更快::

( time ( pvE0 < "${m3t}" |
LC_ALL=C mawk2 'BEGIN {            FS = RS = "^$"  }END { print tolower($(ORS = "")) }'
) | pvE9 ) | xxh128sum| lgp3
in0: 1.85GiB 0:00:00 [3.35GiB/s] [3.35GiB/s] [============>] 100%out9: 1.85GiB 0:00:02 [ 647MiB/s] [ 647MiB/s] [ <=> ]( pvE 0.1 in0 < "${m3t}" | LC_ALL=C mawk2 ; )

1.39s user 1.31s system 91% cpu 2.935 total85759a34df874966d096c6529dbfb9d5  stdin

对于Bash3.2.+|Mac:

read -p 'What is your email? ' emailemail=$(echo $email | tr '[:upper:]' '[:lower:]')email="$email"echo $email