มีวิธีเข้าหรือไม่ ทุบตี การแปลงสตริงเป็นสตริงตัวพิมพ์เล็ก?
ตัวอย่างเช่นถ้าฉันมี:
a="Hi all"
ฉันต้องการแปลงเป็น:
"hi all"
มีวิธีเข้าหรือไม่ ทุบตี การแปลงสตริงเป็นสตริงตัวพิมพ์เล็ก?
ตัวอย่างเช่นถ้าฉันมี:
a="Hi all"
ฉันต้องการแปลงเป็น:
"hi all"
คำตอบ:
มีหลายวิธี:
$ 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 ในกรณีที่ [AZ] ถูกจับคู่อย่างไม่ถูกต้องโดย [AZ] Bash สับสนโดย double-negative ("nocasematch unsetting")! :-)
word="Hi All"
เช่นตัวอย่างอื่น ๆ ก็จะส่งกลับไม่ได้ha
hi all
ใช้งานได้กับตัวพิมพ์ใหญ่และข้ามตัวอักษรที่มีตัวพิมพ์เล็ก
tr
และawk
ตัวอย่างที่ระบุไว้ในมาตรฐาน POSIX
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 tr "[A-Z]" "[a-z]" A
จะทำงานอย่างถูกต้อง
sed
tr [A-Z] [a-z]
ไม่ถูกต้องในเกือบทุกภาษา ตัวอย่างเช่นในen-US
สถานที่เกิดเหตุเป็นจริงช่วงเวลาA-Z
AaBbCcDdEeFfGgHh...XxYyZ
ฉันรู้ว่านี่เป็นโพสต์เก่า แต่ฉันทำคำตอบนี้สำหรับไซต์อื่นดังนั้นฉันคิดว่าฉันโพสต์ไว้ที่นี่:
บน -> ด้านล่าง : ใช้ python:
b=`echo "print '$a'.lower()" | python`
หรือทับทิม:
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`
ด้านล่าง -> บน :
ใช้หลาม:
b=`echo "print '$a'.upper()" | python`
หรือทับทิม:
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
ใช้ GNU sed
:
sed 's/.*/\L&/'
ตัวอย่าง:
$ foo="Some STRIng";
$ foo=$(echo "$foo" | sed 's/.*/\L&/')
$ echo "$foo"
some string
Pre Bash 4.0
Bash ลดขนาดตัวพิมพ์ของสตริงและกำหนดให้กับตัวแปร
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"
echo
และท่อ: ใช้$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
สำหรับเชลล์มาตรฐาน (โดยไม่มี 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
ใน bash 4 คุณสามารถใช้เรียงพิมพ์
ตัวอย่าง:
A="HELLO WORLD"
typeset -l A=$A
คุณสามารถลองสิ่งนี้
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,,}
สัญกรณ์จริงๆ(มันง่ายและเท่ห์) สำหรับ Bash ก่อน 4 (ตัวอย่างเช่น My Mac ยังคงใช้ Bash 3.2) ฉันใช้คำตอบของ @ ghostdog74 เวอร์ชันที่แก้ไขเพื่อสร้างเวอร์ชันพกพามากขึ้น
หนึ่งที่คุณสามารถโทรlowercase 'my STRING'
และรับรุ่นที่เล็กกว่า ฉันอ่านความคิดเห็นเกี่ยวกับการตั้งค่าผลลัพธ์เป็น var แต่นั่นไม่ใช่แบบพกพาจริงๆBash
เนื่องจากเราไม่สามารถส่งคืนสตริงได้ การพิมพ์เป็นทางออกที่ดีที่สุด var="$(lowercase $str)"
ง่ายต่อการจับกับสิ่งที่ต้องการ
วิธีนี้ใช้ได้ผล
วิธีการทำงานนี้คือโดยได้รับการแสดง ASCII จำนวนเต็มของแต่ละถ่านด้วยprintf
แล้วadding 32
ถ้าupper-to->lower
หรือถ้าsubtracting 32
lower-to->upper
จากนั้นใช้printf
อีกครั้งเพื่อแปลงตัวเลขกลับไปที่อักขระ จาก'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 chars ไปเท่านั้น
ฉันกำลังใช้สิ่งนี้สำหรับตัวเลือก CLI ที่คำนึงถึงขนาดตัวพิมพ์ตัวอย่างเช่น
กรณีการแปลงจะทำสำหรับตัวอักษรเท่านั้น ดังนั้นควรทำงานอย่างเรียบร้อย
ฉันมุ่งเน้นการแปลงตัวอักษรระหว่าง az จากตัวพิมพ์ใหญ่เป็นตัวพิมพ์เล็ก ตัวละครอื่นใดที่ควรจะพิมพ์ใน stdout ตามที่มันเป็น ...
แปลงข้อความทั้งหมดในพา ธ / ถึง / ไฟล์ / ชื่อไฟล์ภายในช่วง az เป็น 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}
อนุญาตให้สิ่งนี้ทำงานแม้ว่าสตริงจะมีเครื่องหมายคำพูดสำหรับ Bash เวอร์ชั่นที่เก่ากว่า 4.0 เวอร์ชันนี้ควรเร็วที่สุด (เนื่องจากไม่แยก / เรียกใช้คำสั่งใด ๆ ):
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ก็มีศักยภาพเช่นกันแม้ว่ามันจะทำงานได้อย่างถูกต้องสำหรับ mee ก็ตาม
ทั้งๆที่วิธีการเดิมคำถามนี้และคล้ายกับคำตอบนี้โดย technosaurus ฉันมีปัญหาในการค้นหาโซลูชันที่สามารถพกพาข้ามแพลตฟอร์มส่วนใหญ่ (ที่ฉันใช้) และทุบตีรุ่นที่เก่ากว่า ฉันยังได้รับความผิดหวังกับอาร์เรย์ฟังก์ชั่นและการใช้งานของการพิมพ์ echos และไฟล์ชั่วคราวเพื่อดึงตัวแปรเล็ก ๆ น้อย ๆ มันใช้งานได้ดีมากสำหรับฉันจนฉันคิดว่าฉันจะแบ่งปัน สภาพแวดล้อมการทดสอบหลักของฉันคือ:
- ทุบตี GNU รุ่น 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ง่ายๆ สำหรับการวนซ้ำเพื่อย้ำผ่านสตริง สำหรับสายด้านล่างหากคุณยังไม่เคยเห็นอะไรเช่นนี้มาก่อนที่ นี่คือที่ที่ผมได้เรียนรู้นี้ ในกรณีนี้บรรทัดจะตรวจสอบว่าอักขระถ่าน $ {input: $ i: 1} (ตัวพิมพ์เล็ก) มีอยู่ในอินพุตหรือไม่และถ้าเป็นเช่นนั้นจะแทนที่ด้วยอักขระที่กำหนด $ {ucs: $ j: 1} (ตัวพิมพ์ใหญ่) และเก็บไว้ กลับเข้ามา
input="${input/${input:$i:1}/${ucs:$j:1}}"
นี่เป็นวิธีที่แตกต่างกันอย่างรวดเร็วของวิธี JaredTS486ที่ใช้ความสามารถของ Bash ดั้งเดิม (รวมถึง Bash เวอร์ชัน <4.0) เพื่อปรับวิธีการของเขาให้เหมาะสม
ฉันได้กำหนดวิธีการนี้ 1,000 ครั้งสำหรับสตริงขนาดเล็ก (25 ตัวอักษร) และสตริงที่ใหญ่กว่า (445 ตัวอักษร) ทั้งสำหรับตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ เนื่องจากสตริงการทดสอบเป็นตัวพิมพ์เล็กส่วนใหญ่การแปลงเป็นตัวพิมพ์เล็กโดยทั่วไปจะเร็วกว่าตัวพิมพ์ใหญ่
ฉันได้เปรียบเทียบวิธีการของฉันกับคำตอบอื่น ๆ ในหน้านี้ที่เข้ากันได้กับ Bash 3.2 วิธีการของฉันมีประสิทธิภาพมากกว่าวิธีการส่วนใหญ่ที่บันทึกไว้ที่นี่และเร็วกว่าtr
ในหลายกรณี
นี่คือผลการจับเวลาสำหรับ 1,000 ซ้ำ 25 ตัวอักษร:
tr
ตัวพิมพ์เล็ก; 3.81s สำหรับตัวพิมพ์ใหญ่ผลการจับเวลาสำหรับ 1,000 ซ้ำจำนวน 445 ตัวอักษร (ประกอบด้วยบทกวี "The Robin" โดย Witter Bynner):
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
สามารถเติมได้ด้วยอักขระเพิ่มเติมเพื่อจัดเก็บสตริงที่แปลงแล้วเป็นตัวแปร การติดตามทำงานให้ฉัน -
$SOURCE_NAME
ถึง$TARGET_NAME
TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"
วิธีง่ายๆ
echo "Hi all" | awk '{ print tolower($0); }'