बैश में लोअर केस में स्ट्रिंग कैसे कन्वर्ट करें?


1253

क्या कोई रास्ता है एक स्ट्रिंग को कम केस स्ट्रिंग में बदलने के लिए?

उदाहरण के लिए, अगर मेरे पास:

a="Hi all"

मैं इसे रूपांतरित करना चाहता हूं:

"hi all"

1
इन्हें भी देखें : stackoverflow.com/questions/11392189
dreftymac

जवाबों:


2180

विभिन्न तरीके हैं:

POSIX मानक

टीआर

$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all

AWK

$ echo "$a" | awk '{print tolower($0)}'
hi all

गैर POSIX

आप निम्न उदाहरणों के साथ पोर्टेबिलिटी मुद्दों में भाग सकते हैं:

बाश 4.0

$ echo "${a,,}"
hi all

sed

$ 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 बैश संस्करण 4.2.46 और 4.0.33 (और समान व्यवहार 2.05b.0 लेकिन nocasematch लागू नहीं है) के लिए काम नहीं करता है shopt -u nocasematch;। उस nocasematch को रोकने के कारण [["fooBaR" == "FOObar"]] को अजीब तरह से [bz] गलत तरीके से मिलान किया जाता है [AZ]। बैश दोहरे नकारात्मक ("परेशान nocasematch") द्वारा भ्रमित है! :-)


9
क्या मुझे कुछ याद आ रहा है, या आपका अंतिम उदाहरण (बाश में) वास्तव में कुछ पूरी तरह से अलग है? यह "एबीएक्स" के लिए काम करता है, लेकिन यदि आप इसके बजाय word="Hi All"अन्य उदाहरणों की तरह बनाते हैं, तो यह वापस आ जाता है ha, नहीं hi all। यह केवल बड़े अक्षरों के लिए काम करता है और पहले से ही निचली अक्षरों को छोड़ देता है।
जंगोस्तेव

26
ध्यान दें कि केवल trऔर awkउदाहरण POSIX मानक में निर्दिष्ट हैं।
रिचर्ड हैनसेन

178
tr '[:upper:]' '[:lower:]'अपरकेस / लोअरकेस समतुल्य का निर्धारण करने के लिए वर्तमान लोकेल का उपयोग करेगा, इसलिए यह उन स्थानों के साथ काम करेगा जो वर्णनात्मक अंक वाले अक्षरों का उपयोग करते हैं।
रिचर्ड हैनसेन

10
नए चर में आउटपुट कैसे प्राप्त होता है? Ie का कहना है कि मैं एक नए चर में निचली हुई स्ट्रिंग चाहता हूं?
एडम पार्किं

60
@ एडम:b="$(echo $a | tr '[A-Z]' '[a-z]')"
टीनो

434

बैश 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 द्वारा सुझाया गया है

संपादित करें: बैश 4.3 से मिलान करने के लिए सही टिल्ड व्यवहार।


5
काफी बिज़ारे, "^ ^" और "," ऑपरेटर गैर-ASCII वर्णों पर काम नहीं करते हैं, लेकिन "~~" करता है ... इसलिए string="łódź"; echo ${string~~}"ŹDŹ" लौटाएगा, लेकिन echo ${string^^}"łóDź" लौटाएगा। में भी LC_ALL=pl_PL.utf-8। वह बैश 4.2.24 का उपयोग कर रहा है।
ह्यूबर्ट करियो

2
@HubertKario: यह अजीब है। यह मेरे लिए बैश 4.0.33 में एक ही स्ट्रिंग के साथ समान है en_US.UTF-8। यह एक बग है और मैंने इसे रिपोर्ट किया है।
अगली सूचना तक रोक दिया गया।

1
@HubertKario: प्रयास करें echo "$string" | tr '[:lower:]' '[:upper:]'। यह संभवतः उसी विफलता को प्रदर्शित करेगा। तो समस्या कम से कम आंशिक रूप से बैश की नहीं है।
अगली सूचना तक रोक दिया गया।

1
@ डेनिसविलियम्सन: हाँ, मैंने उस पर भी ध्यान दिया है (शुवालोव के जवाब पर टिप्पणी देखें)। मैं सिर्फ यह कहूंगा, "यह सामान केवल ASCII के लिए है", लेकिन फिर यह "~~" ऑपरेटर है जो काम करता है, इसलिए यह कोड और अनुवाद तालिकाओं की तरह नहीं है ...
ह्यूबर्ट करियो

4
@HubertKario: बैश मेंटेनर ने बग को स्वीकार कर लिया है और कहा है कि इसे अगली रिलीज में तय किया जाएगा।
अगली सूचना तक रोक दिया गया।

123
echo "Hi All" | tr "[:upper:]" "[:lower:]"

4
@ रिचर्डचैन: trमेरे लिए गैर-एसीआईआई पात्रों के लिए काम नहीं करता है। मेरे पास सही लोकल सेट और लोकेल फाइलें उत्पन्न होती हैं। क्या मुझे पता है कि मैं गलत कर सकता हूं?
ह्यूबर्ट करियो जूल

FYI करें: यह Windows / Msys पर काम करता है। कुछ अन्य सुझावों पर अमल नहीं हुआ।
wasatchwizard

3
क्यों [:upper:]जरूरी है?
एमगुट्ट

77

tr :

a="$(tr [A-Z] [a-z] <<< "$a")"

AWK :

{ print tolower($0) }

सीड :

y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/

2
+1 a="$(tr [A-Z] [a-z] <<< "$a")"मुझे सबसे आसान लगता है। मैं अभी भी एक शुरुआत कर रहा हूँ ...
संदीपन नाथ

2
मैं दृढ़ता से sedसमाधान की सिफारिश करता हूं ; मैं एक ऐसे माहौल में काम कर रहा हूं, जो किसी कारण से नहीं है, trलेकिन मुझे अभी तक बिना किसी सिस्टम के ढूंढना है sed, इसके अलावा बहुत से समय मैं ऐसा करना चाहता हूं, मैंने अभी कुछ और किया sedहै, इसलिए चेन कर सकता हूं एक एकल (लंबे) बयान में एक साथ आदेश।
हरविकांक

2
कोष्ठक के भाव उद्धृत किए जाने चाहिए। में tr [A-Z] [a-z] Aअगर कोई एक भी पत्र या से मिलकर फ़ाइल नाम हैं, खोल फ़ाइल नाम विस्तार प्रदर्शन कर सकते हैं nullgob निर्धारित है। tr "[A-Z]" "[a-z]" Aठीक से व्यवहार करेगा।
डेनिस

2
@CamiloMartin यह एक बिजीबॉक्स सिस्टम है जहां मुझे वह समस्या आ रही है, विशेष रूप से Synology NASes, लेकिन मैंने इसे कुछ अन्य सिस्टम पर भी सामना किया है। मैं हाल ही में क्रॉस-प्लेटफ़ॉर्म शेल स्क्रिप्टिंग का एक बहुत कुछ कर रहा हूँ, और आवश्यकता के साथ कि अतिरिक्त कुछ भी स्थापित नहीं किया जाता है इससे चीजें बहुत मुश्किल हो जाती हैं! हालाँकि मैं अभी तक एक प्रणाली का सामना कर रहा हूंsed
हार्विक

2
ध्यान दें कि tr [A-Z] [a-z]लगभग सभी स्थानों में गलत है। उदाहरण के लिए, en-USलोकेल में, A-Zवास्तव में अंतराल है AaBbCcDdEeFfGgHh...XxYyZ
फ़ूज

44

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन मैंने इसका जवाब दूसरी साइट के लिए बनाया है, तो मुझे लगा कि मैं इसे यहाँ पोस्ट करूँगा:

UPPER -> निचला : अजगर का उपयोग करें:

b=`echo "print '$a'.lower()" | python`

या रूबी:

b=`echo "print '$a'.downcase" | ruby`

या पर्ल (शायद मेरा पसंदीदा):

b=`perl -e "print lc('$a');"`

या PHP:

b=`php -r "print strtolower('$a');"`

या अवाक्:

b=`echo "$a" | awk '{ print tolower($1) }'`

या पाल:

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`

या पर्ल (शायद मेरा पसंदीदा):

b=`perl -e "print uc('$a');"`

या PHP:

b=`php -r "print strtoupper('$a');"`

या अवाक्:

b=`echo "$a" | awk '{ print toupper($1) }'`

या पाल:

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

ऊपरी मामले के लिए।


@JESii मेरे लिए ऊपरी -> निचले और निचले-> ऊपरी दोनों काम करते हैं। मैं 64 बिट डेबियन स्ट्रेच पर sed 4.2.2 और बैश 4.3.42 (1) का उपयोग कर रहा हूं।
nettux

1
नमस्ते, @ nettux443 ... मैंने बस फिर से बैश ऑपरेशन की कोशिश की और यह अभी भी मेरे लिए त्रुटि संदेश "खराब प्रतिस्थापन" के साथ विफल रहता है। मैं होमब्रेव बैश का उपयोग करके OSX पर हूँ: GNU बैश, संस्करण 4.3.42 (1) -release (x86_64-apple-darwin14.5.0)
JESii

5
प्रयोग नहीं करें! एक स्क्रिप्ट उत्पन्न करने वाले सभी उदाहरण बेहद भंगुर हैं; यदि aकिसी एकल उद्धरण में मान शामिल है, तो आपके पास न केवल व्यवहार टूट गया है, बल्कि एक गंभीर सुरक्षा समस्या है।
ट्रिपल

मुझे सेड सॉल्यूशन सबसे ज्यादा पसंद है, क्योंकि सेड हमेशा सर्वव्यापी होता है।
डूडी बॉय

मैं dd समाधान का उपयोग करना पसंद करता हूं। कृपया ध्यान दें कि इसे काम करने के लिए आपको रूट होने की आवश्यकता है
inetphantom


18

GNU का उपयोग करना sed:

sed 's/.*/\L&/'

उदाहरण:

$ foo="Some STRIng";
$ foo=$(echo "$foo" | sed 's/.*/\L&/')
$ echo "$foo"
some string

12

प्री बैश 4.0

एक स्ट्रिंग के मामले को कम करें और चर को असाइन करें

VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]') 

echo "$VARIABLE"

5
echoऔर पाइप की आवश्यकता नहीं : उपयोग$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
टीनो

3
@ टीन यहाँ बैश के पुराने संस्करणों के लिए भी वापस पोर्टेबल नहीं है; मेरा मानना ​​है कि इसे v3 में पेश किया गया था।
ट्रिपल जे 1616 '12:28

1
@tripleee आप सही हैं, इसे bash-2.05b में पेश किया गया था - हालाँकि यह सबसे पुराना बैश है जिसे मैं अपने सिस्टम पर ढूंढने में सक्षम था
Tino

11

केवल शेलिंस का उपयोग करके एक मानक शेल (बिना बशीश) के लिए:

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}"
}

मुझे आश्चर्य है कि अगर आपने इस स्क्रिप्ट में कुछ बशीवाद नहीं होने दिया, क्योंकि यह FreeBSD sh: $ {1: $ ...} पर खराब नहीं है: खराब प्रतिस्थापन
Dereckson

2
वास्तव में; ${var:1:1}एक Bashism के साथ substrings हैं।
ट्रिपलए

इस दृष्टिकोण में बहुत बुरा प्रदर्शन मीट्रिक है। मैट्रिक्स के लिए मेरा उत्तर देखें।
देजय क्लेटन

9

बैश 4 में आप टाइपसेट का उपयोग कर सकते हैं

उदाहरण:

A="HELLO WORLD"
typeset -l A=$A


7

नियमित अभिव्यक्ति

मैं जिस आज्ञा को साझा करना चाहता हूं, उसका श्रेय लेना चाहता हूं, लेकिन सच्चाई यह है कि मुझे http://commandlinefu.com से अपने स्वयं के उपयोग के लिए प्राप्त किया गया है । इसका यह फायदा है कि यदि आप cdअपने खुद के होम फोल्डर में किसी भी डायरेक्टरी में हैं, तो यह है कि सभी फाइल और फोल्डर को लोअर केस में बदल दें, कृपया सावधानी से उपयोग करें। यह एक शानदार कमांड लाइन फिक्स है और विशेष रूप से उन एल्बमों के लिए उपयोगी है जिन्हें आपने अपने ड्राइव पर संग्रहीत किया है।

find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

आप वर्तमान निर्देशिका या पूर्ण पथ को दर्शाने वाले खोज के बाद डॉट (।) के स्थान पर एक निर्देशिका निर्दिष्ट कर सकते हैं।

मुझे उम्मीद है कि यह समाधान एक चीज को उपयोगी साबित करता है जो यह आदेश नहीं करता है अंडरस्कोर के साथ रिक्त स्थान को बदलें - ओह अच्छी तरह से एक और समय।


यह मेरे लिए किसी भी कारण से काम नहीं आया, हालांकि यह ठीक लग रहा है। मुझे यह एक विकल्प के रूप में काम करने के लिए मिला: हालांकि। -exec / bin / bash -c 'mv {} `tr [AZ] [az] <<< {}`' \;
जॉन रिक्स

यह जरूरत prenameसे perl: dpkg -S "$(readlink -e /usr/bin/rename)"देता हैperl: /usr/bin/prename
टीनो

4

बाहरी कार्यक्रमों का उपयोग करते हुए कई उत्तर, जो वास्तव में उपयोग नहीं कर रहा है Bash

यदि आप जानते हैं कि आपके पास बैश 4 उपलब्ध होगा तो आपको वास्तव में केवल ${VAR,,}अंकन का उपयोग करना चाहिए (यह आसान और अच्छा है)। 4 से पहले बैश के लिए (मेरा मैक अभी भी उदाहरण के लिए बैश 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 वर्णों के लिए काम करना चाहिए

मेरे लिए यह ठीक है, क्योंकि मुझे पता है कि मैं केवल एएससीआईआई को इसके लिए पास करूंगा।
मैं उदाहरण के लिए कुछ केस-असंवेदनशील सीएलआई विकल्पों के लिए इसका उपयोग कर रहा हूं।


4

परिवर्तित मामला केवल वर्णमाला के लिए किया जाता है। तो, यह बड़े करीने से काम करना चाहिए।

मैं ऊपरी मामले से निचले मामले में az के बीच अक्षर बदलने पर ध्यान केंद्रित कर रहा हूं। किसी भी अन्य पात्रों को बस स्टडआउट में मुद्रित किया जाना चाहिए जैसा कि यह है ...

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

3

यदि 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}अनुमति देता है।

3

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"
}

टेक्नोसॉरस के उत्तर में क्षमता भी थी, हालांकि यह ठीक से चल रहा था।


बुरा नहीं! इस दृष्टिकोण के प्रदर्शन के विश्लेषण के लिए, कृपया मैट्रिक्स के लिए मेरा उत्तर देखें।
देजय क्लेटन

3

इसके बावजूद यह प्रश्न कितना पुराना है और टेक्नोसॉरस के इस जवाब से मिलता-जुलता है । मेरे पास एक मुश्किल समय था जो एक समाधान ढूंढता था जो अधिकांश प्लेटफार्मों (जो मैं उपयोग करता हूं) के साथ-साथ बैश के पुराने संस्करणों में भी पोर्टेबल था। मैं तुच्छ चर को पुनः प्राप्त करने के लिए सरणियों, कार्यों और प्रिंटों, इकोस और अस्थायी फ़ाइलों के उपयोग से भी निराश हो गया हूं। यह मेरे लिए बहुत अच्छा काम करता है अब तक मैंने सोचा था कि मैं साझा करूंगा। मेरे मुख्य परीक्षण वातावरण हैं:

  1. GNU बैश, संस्करण 4.1.2 (1) -release (x86_64-redhat-linux-gnu)
  2. GNU बैश, संस्करण 3.2.57 (1) -release (स्पार्क-सन-सोलारिस 2.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

लूप के लिए सरल सी-शैली स्ट्रिंग्स के माध्यम से पुनरावृति करने के लिए । नीचे की पंक्ति के लिए यदि आपने इससे पहले ऐसा कुछ नहीं देखा है, जहां मैंने यह सीखा है । इस मामले में लाइन चेक करती है कि क्या char $ {इनपुट: $ i: 1} (निचला मामला) इनपुट में मौजूद है और यदि ऐसा है तो दिए गए char $ {ucs: $ j: 1} (ऊपरी मामले) के साथ बदल देता है और इसे संग्रहीत करता है इनपुट में वापस

input="${input/${input:$i:1}/${ucs:$j:1}}"

यह बेतहाशा अक्षम है, ऊपर आपके उदाहरण में 650 बार लूपिंग, और मेरी मशीन पर 1000 चालान निष्पादित करने के लिए 35 सेकंड का समय। एक विकल्प के लिए जो केवल 11 बार लूप करता है और 1000 इनोक्यूशंस को निष्पादित करने में 5 सेकंड से कम समय लेता है, मेरा वैकल्पिक उत्तर देखें।
देजय क्लेटन

1
धन्यवाद, हालांकि यह सिर्फ इसे देखने से स्पष्ट होना चाहिए। शायद पृष्ठ दोष इनपुट आकार और आपके द्वारा निष्पादित किए जाने वाले पुनरावृत्तियों की संख्या से हैं। फिर भी मुझे आपका समाधान पसंद है।
जारेड्ट्स ४18६

3

यह JaredTS486 के दृष्टिकोण का कहीं अधिक तेज़ बदलाव है जो अपने दृष्टिकोण को अनुकूलित करने के लिए देशी बैश क्षमताओं (बाश संस्करणों सहित <4.0) का उपयोग करता है।

मैंने एक छोटे स्ट्रिंग (25 अक्षर) और एक बड़े स्ट्रिंग (445 वर्ण) के लिए इस दृष्टिकोण के 1,000 पुनरावृत्तियों को लोअरकेस और अपरकेस रूपांतरणों के लिए समयबद्ध किया है। चूंकि परीक्षण के तार मुख्य रूप से निचले होते हैं, इसलिए निचले हिस्से के रूपांतरण आमतौर पर अपरकेस की तुलना में अधिक तेज़ होते हैं।

मैंने इस पृष्ठ पर कई अन्य उत्तरों के साथ अपने दृष्टिकोण की तुलना की है जो बैश 3.2 के साथ संगत हैं। मेरा दृष्टिकोण यहां प्रलेखित अधिकांश दृष्टिकोणों की तुलना में कहीं अधिक बेहतर है, और trकई मामलों में इससे भी तेज है ।

यहां 25 वर्णों के 1,000 पुनरावृत्तियों के लिए समय परिणाम दिए गए हैं:

445 पात्रों के 1,000 पुनरावृत्तियों के लिए समय परिणाम (विटर बर्नर द्वारा कविता "द रॉबिन"):

  • लोअरकेस में मेरे दृष्टिकोण के लिए 2s; अपरकेस के लिए 12s
  • trलोअरकेस के लिए 4 एस ; अपरकेस के लिए 4
  • लोअरकेस में ऑरवेलोफाइल के दृष्टिकोण के लिए 20s ; अपरकेस के लिए 29
  • घोस्टडॉग74 के निचले हिस्से के दृष्टिकोण के लिए 75 ; अपरकेस के लिए 669। यह ध्यान रखना दिलचस्प है कि प्रमुख मैचों के साथ एक परीक्षण में कितना नाटकीय अंतर है?
  • टेक्नोसॉरस के निचले हिस्से के दृष्टिकोण के लिए 467 ; अपरकेस के लिए 449 एस
  • JaredTS486 के लिए 660s लोअरकेस के लिए दृष्टिकोण ; अपरकेस के लिए 660s। यह ध्यान रखना दिलचस्प है कि इस दृष्टिकोण ने बैश में निरंतर पृष्ठ दोष (मेमोरी स्वैपिंग) उत्पन्न किया

समाधान:

#!/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}"
}

दृष्टिकोण सरल है: जबकि इनपुट स्ट्रिंग में कोई शेष अपरकेस अक्षर मौजूद है, अगले एक को ढूंढें, और उस पत्र के सभी उदाहरणों को उसके निचले संस्करण के साथ बदलें। सभी अपरकेस अक्षरों को बदलने तक दोहराएं।

मेरे समाधान की कुछ प्रदर्शन विशेषताएँ:

  1. केवल शेल अंतर्निहित उपयोगिताओं का उपयोग करता है, जो एक नई प्रक्रिया में बाहरी बाइनरी उपयोगिताओं को लागू करने के ओवरहेड से बचा जाता है
  2. उप-गोले से बचा जाता है, जो प्रदर्शन के दंड को भड़काता है
  3. शेल तंत्रों का उपयोग करता है जो प्रदर्शन के लिए संकलित और अनुकूलित होते हैं, जैसे कि चर के भीतर वैश्विक स्ट्रिंग प्रतिस्थापन, चर प्रत्यय ट्रिमिंग, और रेगेक्स खोज और मिलान। इन तंत्रों को स्ट्रिंग्स के माध्यम से मैन्युअल रूप से पुनरावृत्ति करने की तुलना में अधिक तेज है
  4. अद्वितीय मिलान वाले वर्णों की गणना के लिए केवल कई बार लूप्स को परिवर्तित करना होगा। उदाहरण के लिए, स्ट्रिंग को तीन अलग-अलग अपरकेस वर्णों में परिवर्तित करने के लिए केवल 3 लूप पुनरावृत्तियों की आवश्यकता होती है। पूर्वनिर्मित ASCII वर्णमाला के लिए, लूप पुनरावृत्तियों की अधिकतम संख्या 26 है
  5. UCSऔर LCSअतिरिक्त पात्रों के साथ संवर्धित किया जा सकता है

2

परिवर्तित स्ट्रिंग को एक चर में संग्रहीत करने के लिए। मेरे लिए काम किया निम्नलिखित - $SOURCE_NAMEकरने के लिए$TARGET_NAME

TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.