Jawaban:
Ada berbagai cara:
$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all
$ echo "$a" | awk '{print tolower($0)}'
hi all
Anda dapat mengalami masalah portabilitas dengan contoh-contoh berikut:
$ 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
Catatan: YMMV yang satu ini. Tidak bekerja untuk saya (GNU bash versi 4.2.46 dan 4.0.33 (dan perilaku yang sama 2.05b.0 tetapi nocasematch tidak diterapkan)) bahkan dengan menggunakan shopt -u nocasematch;
. Tidak mengonfirmasi bahwa nocasematch menyebabkan [["fooBaR" == "FOObar"]] cocok dengan OK TAPI di dalam case aneh [bz] tidak cocok dengan [AZ]. Bash bingung oleh double-negative ("unsetting nocasematch")! :-)
word="Hi All"
seperti contoh-contoh lain, ia kembali ha
, tidak hi all
. Ini hanya berfungsi untuk huruf kapital dan melompati huruf yang sudah lebih kecil.
tr
dan awk
contoh yang ditentukan dalam standar POSIX.
tr '[:upper:]' '[:lower:]'
akan menggunakan lokal saat ini untuk menentukan setara huruf besar / kecil, jadi itu akan berfungsi dengan lokal yang menggunakan huruf dengan tanda diakritik.
b="$(echo $a | tr '[A-Z]' '[a-z]')"
Dalam Bash 4:
Untuk huruf kecil
$ 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
Ke huruf besar
$ 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
Toggle (tidak berdokumen, tetapi dapat dikonfigurasi opsional saat waktu kompilasi)
$ 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
Kapitalisasi (tidak terdokumentasi, tetapi dapat dikonfigurasi secara opsional pada waktu kompilasi)
$ string="a few words"
$ declare -c string
$ string=$string
$ echo "$string"
A few words
Judul kasus:
$ 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
Untuk mematikan declare
atribut, gunakan +
. Sebagai contoh declare +c string
,. Ini memengaruhi penugasan selanjutnya dan bukan nilai saat ini.
The declare
pilihan mengubah atribut dari variabel, tetapi bukan isi. Penugasan kembali dalam contoh saya memperbarui konten untuk menunjukkan perubahan.
Edit:
Menambahkan "beralih karakter pertama dengan kata" ( ${var~}
) seperti yang disarankan oleh ghostdog74 .
Sunting: Perilaku tilde yang diperbaiki agar sesuai dengan Bash 4.3.
string="łódź"; echo ${string~~}
akan mengembalikan "ŁÓDŹ", tetapi echo ${string^^}
mengembalikan "łóDź". Bahkan di LC_ALL=pl_PL.utf-8
. Itu menggunakan bash 4.2.24.
en_US.UTF-8
. Ini bug dan saya sudah melaporkannya.
echo "$string" | tr '[:lower:]' '[:upper:]'
. Mungkin akan menunjukkan kegagalan yang sama. Jadi masalahnya setidaknya sebagian bukan milik Bash.
echo "Hi All" | tr "[:upper:]" "[:lower:]"
tr
tidak berfungsi untuk saya untuk karakter non-ACII. Saya memiliki set lokal yang benar dan file lokal yang dihasilkan. Ada yang tahu apa yang bisa saya lakukan salah?
[:upper:]
dibutuhkan?
a="$(tr [A-Z] [a-z] <<< "$a")"
{ print tolower($0) }
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
a="$(tr [A-Z] [a-z] <<< "$a")"
terlihat paling mudah bagi saya. Saya masih pemula ...
sed
solusinya; Saya telah bekerja di lingkungan yang karena alasan tertentu tidak ada tr
tetapi saya belum menemukan sistem tanpa sed
, ditambah banyak waktu saya ingin melakukan ini, saya hanya melakukan sesuatu yang lain sed
sehingga dapat membuat rantai perintah bersama menjadi satu pernyataan (panjang).
tr [A-Z] [a-z] A
, shell dapat melakukan ekspansi nama file jika ada nama file yang terdiri dari satu huruf atau nullgob diatur. tr "[A-Z]" "[a-z]" A
akan berperilaku baik.
sed
tr [A-Z] [a-z]
salah di hampir semua lokal. misalnya, di en-US
lokal, A-Z
sebenarnya adalah intervalnya AaBbCcDdEeFfGgHh...XxYyZ
.
Saya tahu ini adalah posting lawas tetapi saya membuat jawaban ini untuk situs lain jadi saya pikir saya akan mempostingnya di sini:
UPPER -> lower : use python:
b=`echo "print '$a'.lower()" | python`
Atau Ruby:
b=`echo "print '$a'.downcase" | ruby`
Atau Perl (mungkin favorit saya):
b=`perl -e "print lc('$a');"`
Atau PHP:
b=`php -r "print strtolower('$a');"`
Atau Awk:
b=`echo "$a" | awk '{ print tolower($1) }'`
Atau Sed:
b=`echo "$a" | sed 's/./\L&/g'`
Atau Bash 4:
b=${a,,}
Atau NodeJS jika Anda memilikinya (dan sedikit gila ...):
b=`echo "console.log('$a'.toLowerCase());" | node`
Anda juga bisa menggunakan dd
(tapi saya tidak mau!):
b=`echo "$a" | dd conv=lcase 2> /dev/null`
lebih rendah -> UPPER :
gunakan python:
b=`echo "print '$a'.upper()" | python`
Atau Ruby:
b=`echo "print '$a'.upcase" | ruby`
Atau Perl (mungkin favorit saya):
b=`perl -e "print uc('$a');"`
Atau PHP:
b=`php -r "print strtoupper('$a');"`
Atau Awk:
b=`echo "$a" | awk '{ print toupper($1) }'`
Atau Sed:
b=`echo "$a" | sed 's/./\U&/g'`
Atau Bash 4:
b=${a^^}
Atau NodeJS jika Anda memilikinya (dan sedikit gila ...):
b=`echo "console.log('$a'.toUpperCase());" | node`
Anda juga bisa menggunakan dd
(tapi saya tidak mau!):
b=`echo "$a" | dd conv=ucase 2> /dev/null`
Juga ketika Anda mengatakan 'shell' saya berasumsi maksud Anda bash
tetapi jika Anda dapat menggunakannya zsh
semudah
b=$a:l
untuk huruf kecil dan
b=$a:u
untuk huruf besar.
a
berisi satu kutipan, Anda tidak hanya merusak perilaku, tetapi juga masalah keamanan yang serius.
Dalam zsh:
echo $a:u
Harus cinta zsh!
echo ${(C)a} #Upcase the first char only
Pre Bash 4.0
Bash Turunkan Kasing dari string dan tetapkan ke variabel
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"
echo
dan pipa: gunakan$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
Untuk shell standar (tanpa bashisme) hanya menggunakan builtin:
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}"
}
Dan untuk huruf besar:
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}
adalah Bashism.
Anda bisa mencoba ini
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/
Saya ingin menerima pujian untuk perintah yang ingin saya bagikan tetapi kenyataannya adalah saya mendapatkannya untuk saya gunakan sendiri dari http://commandlinefu.com . Ini memiliki keuntungan bahwa jika Anda cd
ke direktori mana pun di dalam folder home Anda sendiri, itu akan mengubah semua file dan folder menjadi huruf kecil secara rekursi, silakan gunakan dengan hati-hati. Ini adalah perbaikan baris perintah yang brilian dan sangat berguna untuk banyak album yang telah Anda simpan di drive Anda.
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
Anda bisa menentukan direktori sebagai pengganti titik (.) Setelah menemukan yang menunjukkan direktori saat ini atau path lengkap.
Saya harap solusi ini terbukti bermanfaat. Satu hal yang tidak dilakukan perintah ini adalah mengganti spasi dengan garis bawah - oh mungkin lain kali.
prename
dari perl
: dpkg -S "$(readlink -e /usr/bin/rename)"
memberiperl: /usr/bin/prename
Banyak jawaban menggunakan program eksternal, yang sebenarnya tidak digunakan Bash
.
Jika Anda tahu Anda akan memiliki Bash4 tersedia, Anda harus benar-benar hanya menggunakan ${VAR,,}
notasi (mudah dan keren). Untuk Bash sebelum 4 (My Mac masih menggunakan Bash 3.2 misalnya). Saya menggunakan versi koreksi dari jawaban ghostdog74 untuk membuat versi yang lebih portabel.
Anda dapat menelepon lowercase 'my STRING'
dan mendapatkan versi huruf kecil. Saya membaca komentar tentang mengatur hasilnya ke var, tetapi itu tidak benar-benar portabel Bash
, karena kita tidak dapat mengembalikan string. Mencetaknya adalah solusi terbaik. Mudah ditangkap dengan sesuatu seperti var="$(lowercase $str)"
.
Bagaimana ini bekerja?
Cara kerjanya adalah dengan mendapatkan representasi integer ASCII dari masing-masing karakter dengan printf
dan kemudian adding 32
jika upper-to->lower
, atau subtracting 32
jika lower-to->upper
. Kemudian gunakan printf
lagi untuk mengubah nomor kembali menjadi char. Dari 'A' -to-> 'a'
kami memiliki perbedaan 32 karakter.
Menggunakan printf
untuk menjelaskan:
$ printf "%d\n" "'a"
97
$ printf "%d\n" "'A"
65
97 - 65 = 32
Dan ini adalah versi yang berfungsi dengan contoh.
Harap perhatikan komentar dalam kode, karena mereka menjelaskan banyak hal:
#!/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
Dan hasilnya setelah menjalankan ini:
$ ./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!
Ini seharusnya hanya berfungsi untuk karakter ASCII .
Bagi saya itu baik-baik saja, karena saya tahu saya hanya akan memberikan karakter ASCII.
Saya menggunakan ini untuk beberapa opsi CLI case-insensitive, misalnya.
Kasing konversi dilakukan hanya untuk huruf. Jadi, ini harus bekerja dengan rapi.
Saya fokus pada konversi huruf antara az dari huruf besar ke huruf kecil. Setiap karakter lain hanya boleh dicetak di stdout karena ...
Mengonversi semua teks di jalur / ke / file / nama file dalam rentang az ke AZ
Untuk mengubah huruf kecil menjadi huruf besar
cat path/to/file/filename | tr 'a-z' 'A-Z'
Untuk mengkonversi dari huruf besar ke huruf kecil
cat path/to/file/filename | tr 'A-Z' 'a-z'
Sebagai contoh,
nama file:
my name is xyz
dikonversi menjadi:
MY NAME IS XYZ
Contoh 2:
echo "my name is 123 karthik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 KARTHIK
Contoh 3:
echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
Jika menggunakan v4, ini dibakar . Jika tidak, berikut ini adalah solusi sederhana dan dapat diterapkan secara luas . Jawaban lain (dan komentar) pada utas ini cukup membantu dalam membuat kode di bawah ini.
# 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:] )\'
}
Catatan:
a="Hi All"
lalu: lcase a
akan melakukan hal yang sama seperti:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
alih-alih ${!1}
memungkinkan ini berfungsi bahkan ketika string memiliki tanda kutip.Untuk versi Bash lebih awal dari 4.0, versi ini harus paling cepat (karena tidak bercabang / mengeksekusi perintah apa pun):
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"
}
jawaban technosaurus memiliki potensi juga, meskipun itu berjalan dengan baik untukku.
Terlepas dari berapa usia pertanyaan ini dan mirip dengan jawaban ini oleh technosaurus . Saya kesulitan menemukan solusi yang portabel di sebagian besar platform (Itu Saya Gunakan) serta versi bash yang lebih lama. Saya juga merasa frustrasi dengan array, fungsi dan penggunaan cetakan, gema dan file sementara untuk mengambil variabel sepele. Ini bekerja dengan sangat baik untuk saya sejauh ini saya pikir saya akan berbagi. Lingkungan pengujian utama saya adalah:
- GNU bash, versi 4.1.2 (1) -release (x86_64-redhat-linux-gnu)
- GNU bash, versi 3.2.57 (1) -release (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
Gaya C sederhana untuk loop untuk beralih melalui string. Untuk baris di bawah ini jika Anda belum melihat yang seperti ini sebelumnya ini adalah tempat saya belajar ini . Dalam kasus ini, baris akan memeriksa apakah char $ {input: $ i: 1} (huruf kecil) ada di input dan jika demikian menggantinya dengan char $ {ucs: $ j: 1} (huruf besar) dan menyimpannya kembali ke input.
input="${input/${input:$i:1}/${ucs:$j:1}}"
Ini adalah variasi yang jauh lebih cepat dari pendekatan JaredTS486 yang menggunakan kemampuan Bash asli (termasuk versi Bash <4.0) untuk mengoptimalkan pendekatannya.
Saya telah menghitung 1.000 iterasi pendekatan ini untuk string kecil (25 karakter) dan string lebih besar (445 karakter), baik untuk konversi huruf kecil dan besar. Karena string tes sebagian besar adalah huruf kecil, konversi ke huruf kecil umumnya lebih cepat daripada huruf besar.
Saya telah membandingkan pendekatan saya dengan beberapa jawaban lain di halaman ini yang kompatibel dengan Bash 3.2. Pendekatan saya jauh lebih berkinerja daripada kebanyakan pendekatan yang didokumentasikan di sini, dan bahkan lebih cepat daripada tr
dalam beberapa kasus.
Berikut adalah hasil waktu untuk 1.000 iterasi 25 karakter:
tr
untuk huruf kecil; 3.81s untuk huruf besarWaktu hasil untuk 1.000 iterasi dari 445 karakter (terdiri dari puisi "The Robin" oleh Witter Bynner):
tr
menjadi huruf kecil; 4s untuk huruf besarLarutan:
#!/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}"
}
Pendekatannya sederhana: sementara string input memiliki huruf besar yang tersisa, temukan yang berikutnya, dan ganti semua instance dari huruf itu dengan varian huruf kecilnya. Ulangi sampai semua huruf besar diganti.
Beberapa karakteristik kinerja solusi saya:
UCS
dan LCS
dapat ditambah dengan karakter tambahan