文字列を小文字の文字列に変換するbashの方法はありますか?
たとえば、私が持っている場合:
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
注: この 1 つの YMMV。を使用しても機能しません(GNU bashバージョン4.2.46および4.0.33(および同じ動作2.05b.0ですが、nocasematchは実装されていません))shopt -u nocasematch;
。nocasematch を設定解除すると、[[ "fooBaR" == "FOObar" ]] は一致しますが、奇妙なことに [bz] は [AZ] によって誤って一致します。Bash は、二重否定 (「nocasematch の設定解除」) によって混乱します! :-)
バッシュ 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 に合わせてチルダの動作を修正しました。
echo "Hi All" | tr "[:upper:]" "[:lower:]"
これは古い投稿であることは知っていますが、別のサイトに対してこの回答を作成したので、ここに投稿すると思いました。
UPPER -> Lower : 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) }'`
またはセド:
b=`echo "$a" | sed 's/./\L&/g'`
またはバッシュ 4:
b=${a,,}
または NodeJS:
b=`node -p "\"$a\".toLowerCase()"`
次を使用することもできます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) }'`
またはセド:
b=`echo "$a" | sed 's/./\U&/g'`
またはバッシュ 4:
b=${a^^}
または NodeJS:
b=`node -p "\"$a\".toUpperCase()"`
次を使用することもできますdd
。
b=`echo "$a" | dd conv=ucase 2> /dev/null`
また、「シェル」と言うときは、あなたが意味しているとbash
思いますが、使用できる場合は次zsh
のように簡単です
b=$a:l
小文字と
b=$a:u
大文字用。
Bash 5.1L
は、パラメーター変換を使用してこれを行う簡単な方法を提供します。
${var@L}
たとえば、次のように言えます。
$ v="heLLo"
$ echo "${v@L}"
hello
で大文字にすることもできますU
:
$ v="hello"
$ echo "${v@U}"
HELLO
そして、最初の文字を大文字にしますu
:
$ v="hello"
$ echo "${v@u}"
Hello
zshの場合:
echo $a:u
zshが大好きです!
GNU の使用sed
:
sed 's/.*/\L&/'
例:
$ foo="Some STRIng";
$ foo=$(echo "$foo" | sed 's/.*/\L&/')
$ echo "$foo"
some string
ビルトインのみを使用する標準シェル(バシズムなし)の場合:
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}"
}
bash 4 では typeset を使用できます
例:
A="HELLO WORLD"
typeset -l A=$A
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/null
abcÆØÅ
共有したいコマンドの功績を認めたいと思いますが、実際にはhttp://commandlinefu.comから自分で使用するために取得しました。cd
自分のホーム フォルダ内の任意のディレクトリにアクセスすると、すべてのファイルとフォルダが再帰的に小文字に変更されるという利点があります。注意して使用してください。これは見事なコマンド ライン修正であり、ドライブに保存されている多数のアルバムに特に役立ちます。
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
現在のディレクトリまたはフル パスを示す find の後のドット (.) の代わりにディレクトリを指定できます。
このソリューションが役立つことを願っています。このコマンドが実行しないことの 1 つは、スペースをアンダースコアに置き換えることです。
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}
使用すると、文字列に引用符が含まれている場合でもこれが機能します。変換された文字列を変数に格納します。以下は私のために働いた -
$SOURCE_NAME
に$TARGET_NAME
TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"
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) リリース (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 スタイルの for ループ。以下の行については、これまでに このようなものを見たことがない場合は、私がこれを学んだ場所です. この場合、行は char ${input:$i:1} (小文字) が入力に存在するかどうかをチェックし、存在する場合はそれを指定された char ${ucs:$j:1} (大文字) に置き換えて格納します。入力に戻ります。
input="${input/${input:$i:1}/${ucs:$j:1}}"