回答:
さまざまな方法があります。
$ 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に一致しますが、奇妙なことに[bz]が[AZ]によって誤って一致します。bashはダブルネガティブ(「unset nocasematch」の設定解除)と混同されています!:-)
word="Hi All"
、他の例のように、それを返しha
、ありませんhi all
。大文字の文字に対してのみ機能し、すでに小文字の文字はスキップします。
tr
とのawk
例のみがPOSIX標準で指定されていることに注意してください。
tr '[:upper:]' '[:lower:]'
現在のロケールを使用して、対応する大文字/小文字を判別するため、発音区別符号付きの文字を使用するロケールで機能します。
b="$(echo $a | tr '[A-Z]' '[a-z]')"
バッシュ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
オプションは、変数の属性ではなく内容を変更します。私の例での再割り当ては、内容を更新して変更を示します。
編集:
ghostdog74の${var~}
提案に従い、「単語ごとに最初の文字を切り替える」()を追加。
編集:チルダの動作を修正して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:]'
。おそらく同じ障害が発生します。したがって、問題は少なくとも部分的にはバッシュのものではありません。
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
とにかく何か他のことをしたので、コマンドを1つの(長い)ステートメントにまとめます。
tr [A-Z] [a-z] A
、1文字で構成されるファイル名がある場合、または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`
または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'`
またはバッシュ4:
b=${a,,}
または、NodeJSをお持ちの場合(そして少しおかしい場合...):
b=`echo "console.log('$a'.toLowerCase());" | node`
あなたも使うことができます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'`
またはバッシュ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
Pre Bash 4.0
文字列の大文字小文字を小文字にして変数に代入する
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"
echo
パイプの必要なし:使用$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
ビルトインのみを使用する標準のシェル(bashismなし)の場合:
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}
はバシズムです。
あなたはこれを試すことができます
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/
共有したいコマンドを信用したいのですが、本当はhttp://commandlinefu.comから自分で使用するために取得しました。それはあなたの場合は、その利点を持っているcd
ことは注意して下ケース再帰的にしてください使用するすべてのファイルとフォルダを変更しますです、あなた自身のホームフォルダ内の任意のディレクトリに移動します。これは見事なコマンドライン修正であり、ドライブに保存した多数のアルバムに特に役立ちます。
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
現在のディレクトリまたは完全パスを示す検索の後に、ドット(。)の代わりにディレクトリを指定できます。
このソリューションが役立つことを願っています。このコマンドが実行しないことの1つは、スペースをアンダースコアに置き換えることです。
prename
からperl
:dpkg -S "$(readlink -e /usr/bin/rename)"
与えperl: /usr/bin/prename
多くの回答は、実際にはを使用していない外部プログラムを使用していBash
ます。
Bash4を使用できることがわかっている場合は、${VAR,,}
表記法を使用するだけです(簡単でクールです)。4より前のBashの場合(たとえば、私のMacはまだBash 3.2を使用しています)。@ ghostdog74の回答の修正バージョンを使用して、よりポータブルなバージョンを作成しました。
呼び出しlowercase 'my STRING'
て小文字バージョンを取得できるもの。結果をvarに設定することについてのコメントを読みましたがBash
、文字列を返すことができないため、では移植性がありません。印刷するのが最善の解決策です。のようなものでキャプチャするのは簡単var="$(lowercase $str)"
です。
この仕組み
これが機能する方法は、各文字のASCII整数表現を取得しprintf
、次にadding 32
if upper-to->lower
、またはsubtracting 32
ifを取得することですlower-to->upper
。次に、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 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文字のみを渡すことを知っているので、私にとっては問題ありません。
たとえば、大文字と小文字を区別しない一部のCLIオプションにこれを使用しています。
大文字と小文字の変換は、アルファベットに対してのみ行われます。したがって、これはきちんと機能するはずです。
私はアルファベットの大文字と小文字を大文字から小文字に変換することに焦点を当てています。他の文字はそのまま標準出力に印刷する必要があります...
z範囲内のpath / to / file / filename内のすべてのテキストを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"
and then:lcase a
は以下と同じことを行います:a=$( echolcase "Hi All" )
${!1//\'/"'\''"}
代わりにを${!1}
使用すると、文字列に引用符がある場合でもこれを機能させることができます。4.0より前のバージョンのBashの場合、このバージョンは最速である必要があります(コマンドをfork / execしないため):
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"
}
テクノサウルスの答えにも可能性はありましたが、私には適切に動作しました。
この質問がどれだけ古くても、テクノサウルスによるこの回答に似ています。古いバージョンのbashだけでなく、ほとんどのプラットフォーム(使用するもの)で移植可能なソリューションを見つけるのに苦労しました。また、配列、関数、および簡単な変数を取得するための印刷、エコー、一時ファイルの使用にも不満を感じています。これは、これまで共有したいと思っていた私にとって非常にうまく機能しています。私の主なテスト環境は次のとおりです。
- GNU bash、バージョン4.1.2(1)-release(x86_64-redhat-linux-gnu)
- GNU bash、バージョン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
文字列を反復処理する単純なCスタイルのforループ。以下の行で、これまでにこのようなものを見たことがない場合 は、これが私がこれを学んだ場所です。この場合、行は文字$ {input:$ i:1}(小文字)が入力に存在するかどうかをチェックし、存在する場合は指定された文字$ {ucs:$ j:1}(大文字)に置き換えて格納します。入力に戻ります。
input="${input/${input:$i:1}/${ucs:$j:1}}"
これは、ネイティブのBash機能(Bashバージョン<4.0を含む)を使用して彼のアプローチを最適化するJaredTS486のアプローチのはるかに高速なバリエーションです。
小文字の変換と大文字の変換の両方で、小さな文字列(25文字)と大きな文字列(445文字)に対して、このアプローチの1,000回の反復を計測しました。テスト文字列は主に小文字であるため、小文字への変換は通常、大文字への変換よりも高速です。
私のアプローチを、このページでBash 3.2と互換性のある他のいくつかの回答と比較しました。私のアプローチは、ここで説明するほとんどのアプローチよりもはるかにパフォーマンスが高くtr
、いくつかのケースよりもさらに高速です。
次に、25文字の1,000回の反復のタイミング結果を示します。
tr
小文字に3.67秒。大文字の3.81s445文字の1,000回の反復のタイミング結果(Witter Bynnerによる詩「The Robin」から成る):
tr
小文字の場合は4秒。大文字は4秒解決:
#!/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
追加の文字を増強することができます