Yanıtlar:
Çeşitli yollar vardır:
$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all
$ echo "$a" | awk '{print tolower($0)}'
hi all
Aşağıdaki örneklerle taşınabilirlik sorunlarıyla karşılaşabilirsiniz:
$ 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
Not: Bu konuda YMMV. Benim için çalışmıyor (GNU bash sürüm 4.2.46 ve 4.0.33 (ve aynı davranış 2.05b.0 ancak nocasematch uygulanmadı)) shopt -u nocasematch;
. Nocasematch'in [["fooBaR" == "FOObar"]] öğesinin, [bz] tuhaf bir şekilde [AZ] ile yanlış eşleştirilmesi durumunda Tamam AMA ile eşleşmesine neden olduğunda. Bash, çift negatif ("ayarsız nocasematch") ile karıştırılır! :-)
word="Hi All"
diğer örneklerde olduğu gibi, bu döner ha
değil hi all
. Yalnızca büyük harfler için çalışır ve zaten küçük harfleri atlar.
tr
ve awk
örneklerinin belirtildiğini unutmayın .
tr '[:upper:]' '[:lower:]'
büyük / küçük harf eşdeğerlerini belirlemek için geçerli yerel ayarı kullanır, böylece aksan işaretli harfler kullanan yerel ayarlarla çalışır.
b="$(echo $a | tr '[A-Z]' '[a-z]')"
Bash 4'te:
Küçük harf yapmak
$ 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
Büyük harfe
$ 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
Geçiş yap (belgelenmemiş, ancak derleme zamanında isteğe bağlı olarak yapılandırılabilir)
$ 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
Büyük harf kullanımı (belgesiz, ancak isteğe bağlı olarak derleme zamanında yapılandırılabilir)
$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words
Başlık durumu:
$ 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
Bir declare
özelliği kapatmak için tuşunu kullanın +
. Örneğin declare +c string
,. Bu, geçerli değeri değil, sonraki atamaları etkiler.
declare
Seçenekler değişkenin niteliğini değil, içeriği değişir. Örneklerimdeki yeniden atamalar, değişiklikleri göstermek için içeriği günceller.
Düzenle:
Ghostdog74${var~}
tarafından önerildiği gibi "kelimeye göre ilk karakteri değiştir" ( ) eklendi .
Düzenleme: Bash 4.3 eşleşmesi için düzeltilmiş tilde davranışı düzeltildi.
string="łódź"; echo ${string~~}
, ancak echo ${string^^}
"łóDź" döndürür. Hatta LC_ALL=pl_PL.utf-8
. Bash 4.2.24 kullanıyor.
en_US.UTF-8
. Bu bir hata ve bunu rapor ettim.
echo "$string" | tr '[:lower:]' '[:upper:]'
. Muhtemelen aynı başarısızlığı sergileyecektir. Yani sorun en azından kısmen Bash'ın değil.
echo "Hi All" | tr "[:upper:]" "[:lower:]"
tr
dışı karakterler için benim için çalışmıyor. Doğru yerel ayar kümesi ve yerel dosyaları oluşturulan var. Neyi yanlış yapabileceğime dair bir fikrin var mı?
[:upper:]
ihtiyaç duyulur?
a="$(tr [A-Z] [a-z] <<< "$a")"
{ print tolower($0) }
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
a="$(tr [A-Z] [a-z] <<< "$a")"
benim için en kolay görünüyor. Hala
sed
Çözümü şiddetle tavsiye ederim ; Bir sebepten ötürü olmayan bir ortamda çalışıyordum tr
ama henüz bir sistem bulamadım sed
, artı bunu yapmak istediğim çoğu zaman sed
zaten başka bir şey yaptım zaten komutları birlikte tek (uzun) bir ifadeye dönüştürür.
tr [A-Z] [a-z] A
, tek bir harf veya nullgob içeren dosya adları varsa kabuk dosya adı genişletmesi gerçekleştirebilir . tr "[A-Z]" "[a-z]" A
düzgün davranacaktır.
sed
tr [A-Z] [a-z]
neredeyse tüm yerel ayarlarda yanlış olduğunu unutmayın . örneğin, en-US
yerel ayar, A-Z
aslında aralıktır AaBbCcDdEeFfGgHh...XxYyZ
.
Bu eski bir yazı olduğunu biliyorum ama bu cevabı başka bir site için yaptım, bu yüzden buraya göndereceğimi düşündüm:
ÜST -> alt : python kullan:
b=`echo "print '$a'.lower()" | python`
Veya Ruby:
b=`echo "print '$a'.downcase" | ruby`
Veya Perl (muhtemelen benim favorim):
b=`perl -e "print lc('$a');"`
Veya PHP:
b=`php -r "print strtolower('$a');"`
Veya Awk:
b=`echo "$a" | awk '{ print tolower($1) }'`
Veya Sed:
b=`echo "$a" | sed 's/./\L&/g'`
Veya Bash 4:
b=${a,,}
Veya NodeJS'iniz varsa (ve biraz deli iseniz ...):
b=`echo "console.log('$a'.toLowerCase());" | node`
Ayrıca kullanabilirsiniz dd
(ama olmaz!):
b=`echo "$a" | dd conv=lcase 2> /dev/null`
alt -> ÜST :
python kullan:
b=`echo "print '$a'.upper()" | python`
Veya Ruby:
b=`echo "print '$a'.upcase" | ruby`
Veya Perl (muhtemelen benim favorim):
b=`perl -e "print uc('$a');"`
Veya PHP:
b=`php -r "print strtoupper('$a');"`
Veya Awk:
b=`echo "$a" | awk '{ print toupper($1) }'`
Veya Sed:
b=`echo "$a" | sed 's/./\U&/g'`
Veya Bash 4:
b=${a^^}
Veya NodeJS'iniz varsa (ve biraz deli iseniz ...):
b=`echo "console.log('$a'.toUpperCase());" | node`
Ayrıca kullanabilirsiniz dd
(ama olmaz!):
b=`echo "$a" | dd conv=ucase 2> /dev/null`
Ayrıca 'kabuk' derken ne demek tahmin ediyorum bash
ama kullanabilirsiniz eğer zsh
kolay olduğu kadar var
b=$a:l
küçük harf ve
b=$a:u
büyük harf için.
a
tek bir teklif içeriyorsa, yalnızca davranışı değil ciddi bir güvenlik sorununu da çözdünüz demektir.
Zsh dilinde:
echo $a:u
Zsh'ı sevmeliyim!
echo ${(C)a} #Upcase the first char only
Ön Bash 4.0
Bash Bir dizgenin Büyük / Küçük Harf Durumunu Azalt ve değişken
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"
echo
Ve borulara gerek yok : kullanım$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
Yalnızca yerleşikleri kullanan standart bir kabuk için (bashisms olmadan):
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}"
}
Ve büyük harf için:
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}
bir Bashizmdir.
Bunu deneyebilirsin
s="Hello World!"
echo $s # Hello World!
a=${s,,}
echo $a # hello world!
b=${s^^}
echo $b # HELLO WORLD!
ref: http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/
Paylaşmak istediğim komut için kredi almak istiyorum ama gerçek şu ki, kendi kullanımım için http://commandlinefu.com adresinden edindim . Bu avantaja sahiptir eğer cd
o yinelemeli harfe dikkatli kullanımını memnun etmek tüm dosya ve klasörleri değişecek olan kendi ev klasörü içinde herhangi bir dizine. Mükemmel bir komut satırı düzeltmesi ve özellikle sürücünüzde sakladığınız çok sayıda albüm için kullanışlıdır.
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
Bulunduktan sonra, geçerli dizini veya tam yolu belirten nokta (.) Yerine bir dizin belirtebilirsiniz.
Umarım bu çözüm, bu komutun yapmadığı bir şeyi boşlukları alt çizgilerle değiştirmektir - ah başka bir zaman.
prename
dan perl
: dpkg -S "$(readlink -e /usr/bin/rename)"
verirperl: /usr/bin/prename
Gerçekten kullanmayan harici programları kullanarak birçok cevap Bash
.
Bash4'ü kullanabileceğinizi biliyorsanız gerçekten ${VAR,,}
notasyonu kullanmalısınız (kolay ve havalı). 4'ten önceki Bash için (Mac'im hala Bash 3.2 kullanıyor). Daha taşınabilir bir sürüm oluşturmak için @ ghostdog74 yanıtının düzeltilmiş sürümünü kullandım.
Birini arayabilir lowercase 'my STRING'
ve küçük harfli bir sürüm alabilirsiniz. Sonucu bir var değerine ayarlama hakkındaki yorumları okudum, ancak Bash
dizeleri döndüremeyeceğimiz için bu gerçekten taşınabilir değil. Yazdırmak en iyi çözümdür. Gibi bir şey ile yakalamak kolay var="$(lowercase $str)"
.
Bu nasıl çalışır?
Bunun çalışma şekli, her bir karakterin ASCII tamsayı temsilini printf
ve sonra adding 32
if upper-to->lower
veya subtracting 32
if ile elde etmektir lower-to->upper
. Sonra printf
numarayı tekrar karaktere dönüştürmek için tekrar kullanın. Gönderen 'A' -to-> 'a'
biz 32 karakterlerin bir fark var.
Açıklamak için kullanma printf
:
$ printf "%d\n" "'a"
97
$ printf "%d\n" "'A"
65
97 - 65 = 32
Ve bu örneklerle çalışan versiyon.
Bir çok şeyi açıkladıkları için lütfen koddaki yorumları not edin:
#!/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
Ve bunu çalıştırdıktan sonra sonuçlar:
$ ./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!
Bu sadece ASCII karakterleri için çalışmalıdır .
Benim için sorun değil, çünkü sadece ASCII karakterlerini aktaracağımı biliyorum.
Örneğin, büyük / küçük harfe duyarlı olmayan CLI seçenekleri için kullanıyorum.
Dönüştürme durumu yalnızca alfabe için yapılır. Yani, bu düzgün çalışmalı.
Az harfli harfleri büyük harften küçük harfe dönüştürmeye odaklanıyorum. Diğer karakterler sadece olduğu gibi stdout'ta yazdırılmalıdır ...
Az aralıktaki yol / dosya / dosya adı içindeki tüm metni AZ'ye dönüştürür
Küçük harfleri büyük harfe dönüştürmek için
cat path/to/file/filename | tr 'a-z' 'A-Z'
Büyük harften küçük harfe dönüştürmek için
cat path/to/file/filename | tr 'A-Z' 'a-z'
Örneğin,
dosya adı:
my name is xyz
dönüştürülür:
MY NAME IS XYZ
Örnek 2:
echo "my name is 123 karthik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 KARTHIK
Örnek 3:
echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
V4 kullanıyorsanız, bu pişmiş . Değilse, burada basit ve yaygın olarak uygulanabilir bir çözüm var. Bu ileti dizisindeki diğer yanıtlar (ve yorumlar) aşağıdaki kodu oluştururken oldukça yardımcı oldu.
# 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:] )\'
}
Notlar:
a="Hi All"
ve sonra: lcase a
aynı şeyi yapacaktır:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
bunun yerine kullanmak ${!1}
, dizede tırnak işareti olsa bile çalışmasına izin verir.4.0'dan önceki Bash sürümleri için, bu sürüm en hızlı olmalıdır ( herhangi bir komutu çatallama / çalıştırmadığından ):
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'un cevabı da benim için doğru bir şekilde çalışmasına rağmen potansiyeli vardı.
Bu sorunun kaç yaşında olmasına rağmen ve technosaurus'un bu cevabına benzer . Çoğu platformda (That I Use) yanı sıra bash'ın eski sürümlerinde taşınabilir bir çözüm bulmakta zorlandım. Ayrıca önemsiz değişkenleri almak için diziler, işlevler ve baskılar, ekolar ve geçici dosyaların kullanımı ile de hayal kırıklığına uğradım. Bu benim için şimdiye kadar çok iyi çalışıyor, paylaşacağımı düşündüm. Ana test ortamlarım:
- GNU bash, sürüm 4.1.2 (1) -çalışma (x86_64-redhat-linux-gnu)
- GNU bash, sürüm 3.2.57 (1) -çalışma (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
Dizeleri yinelemek için döngü için basit C stili . Aşağıdaki satır için daha önce böyle bir şey görmediyseniz , bunu öğrendim . Bu durumda satır, girişte $ {input: $ i: 1} (küçük harf) karakterinin var olup olmadığını kontrol eder ve eğer öyleyse verilen char $ {ucs: $ j: 1} (büyük harf) ile değiştirir ve saklar geri girdi.
input="${input/${input:$i:1}/${ucs:$j:1}}"
Bu, yaklaşımını optimize etmek için yerel Bash yeteneklerini (Bash sürümleri <4.0 dahil) kullanan JaredTS486'nın yaklaşımının çok daha hızlı bir varyasyonudur .
Küçük ve dize dönüşümleri için küçük bir dize (25 karakter) ve daha büyük bir dize (445 karakter) için bu yaklaşımın 1.000 yinelemesini zamanladım. Test dizeleri ağırlıklı olarak küçük harf olduğundan, küçük harfe dönüştürmeler genellikle büyük harfe göre daha hızlıdır.
Yaklaşımımı, bu sayfada Bash 3.2 ile uyumlu diğer birkaç cevapla karşılaştırdım. Benim yaklaşımım burada belgelenen çoğu yaklaşımdan çok daha başarılıdır tr
ve bazı durumlarda olduğundan daha hızlıdır .
İşte 25 karakterlik 1.000 yineleme için zamanlama sonuçları:
tr
Küçük harf için 3.67s ; Büyük harf için 3.81s445 karakterlik 1.000 tekrarlama için zamanlama sonuçları (Witter Bynner'ın "The Robin" şiirinden oluşur):
tr
Küçük harf için 4 s ; Büyük harf için 4sÇözüm:
#!/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}"
}
Yaklaşım basittir: giriş dizesinde kalan büyük harfler varsa, bir sonrakini bulun ve bu harfin tüm örneklerini küçük harfli değişkenle değiştirin. Tüm büyük harfler değiştirilene kadar tekrarlayın.
Çözümümün bazı performans özellikleri:
UCS
ve LCS
ek karakterlerle zenginleştirilebilir