बैश के साथ एक चर में अपरकेस पहला चरित्र


162

मैं बैश के साथ अपने स्ट्रिंग में सिर्फ पहले पात्र को अपरकेस करना चाहता हूं।

foo="bar";

//uppercase first character

echo $foo;

"बार" प्रिंट करना चाहिए;


1
यह एक सटीक डुप्लिकेट नहीं है, लेकिन बैश शेल स्क्रिप्टिंग में कंवर्टिंग स्ट्रिंग टू लोअर केस में वर्णित कई तकनीकों को भी इस समस्या पर लागू किया जा सकता है।
19

जवाबों:


148
foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"

2
सर्वश्रेष्ठ स्कोर किए गए उत्तर की तुलना में अधिक जटिल होने के बावजूद, यह वास्तव में ठीक वैसा ही करता है: 'अपरकेस पहले वर्ण में'। सर्वश्रेष्ठ स्कोर वाले उत्तर के परिणाम नहीं होते हैं। लगता है कि सरल उत्तर सही लोगों की तुलना में अधिक स्वेच्छा से उत्कीर्ण हैं?
Krzysztof Jabłoński

15
@ KrzysztofJabłoński: वास्तव में, नीचे "सर्वश्रेष्ठ स्कोर किया गया उत्तर" बैश 4 के तहत इस उत्तर के समान परिणाम देगा। इस उत्तर में एक सबशेल (एक अन्य शेल) कॉल करने का ओवरहेड है, जो 'tr' उपयोगिता (एक अन्य प्रक्रिया) को कॉल करता है। , बैश नहीं), यहाँ-डॉक्टर / स्ट्रिंग (अस्थायी फ़ाइल निर्माण) का उपयोग करने का ओवरहेड और यह सर्वश्रेष्ठ स्कोर किए गए उत्तर की तुलना में दो प्रतिस्थापन का उपयोग करता है। यदि आपको पूरी तरह से विरासत कोड लिखना चाहिए, तो एक उपधारा के बजाय एक फ़ंक्शन का उपयोग करने पर विचार करें।
स्टीव

2
यह उत्तर मानता है कि इनपुट सभी निम्न स्थिति है। इस प्रकार की कोई धारणा नहीं है: $ (tr '[: निचला:]' ': [: ऊपरी:]' <<< $ {foo: 0: 1}) $ (tr '[: ऊपरी:]' ': [: निचला: ] '<<< $ {foo: 1})
इटाई हांसकी

5
@ इताहंसकी ओपी ने यह निर्दिष्ट नहीं किया कि शेष पात्रों के लिए क्या होना चाहिए, केवल पहले। माना कि वे notQuiteCamelमें बदलना चाहते थे NotQuiteCamel। आपके संस्करण का साइड इफेक्ट है या शेष को निचले हिस्से के लिए मजबूर करना - उप गोले और ट्र प्रक्रियाओं की संख्या को दोगुना करने की लागत पर।
जेसी चिशोल्म

3
@DanieleOrlando, सच है, लेकिन इस सवाल के अलावा कोई टैग नहीं है bash
चार्ल्स डफी

314

बैश के साथ एक तरीका (संस्करण 4+):

foo=bar
echo "${foo^}"

प्रिंट:

Bar

2
क्या इसके विपरीत है?
CMCDragonkai 12

44
@CMCDragonkai: पहले अक्षर को कम करने के लिए, का उपयोग करें "${foo,}"। सभी अक्षरों को कम करने के लिए, का उपयोग करें "${foo,,}"। सभी अक्षरों को अपरकेस करने के लिए, उपयोग करें "${foo^^}"
स्टीव

1
मैंने गलती से कि देखा ${foo~}और ${foo~~}रूप में एक ही प्रभाव है ${foo^}और ${foo^^}। लेकिन मैंने कभी भी उस विकल्प का उल्लेख नहीं किया।
मिवक

5
यह Macs पर काम नहीं करता है। निम्नलिखित त्रुटि हो रही है:bad substitution
टॉलैंड माननीय

1
@TolandHon: जैसा कि आप शायद पहले ही काम कर चुके हैं, आपको संस्करण 4.x में अपग्रेड करने की आवश्यकता होगी, या किसी अन्य समाधान की कोशिश करें यदि उस मशीन को किसी कारण से अपग्रेड नहीं किया जा सकता है।
स्टीव

29

इसके साथ एक तरीका sed:

echo "$(echo "$foo" | sed 's/.*/\u&/')"

प्रिंटों:

Bar

10
MacOS10 लायन सेड पर काम नहीं करता है, आह, \ u एक ऑपरेटर होने के बजाय यू तक फैलता है।
vwvan

2
@vwvan brew install coreutils gnu-sedऔर उपसर्ग के बिना कमांड का उपयोग करने के निर्देशों का पालन करें g। जीएनयू संस्करण प्राप्त करने के बाद से इन कमांडों के ओएसएक्स संस्करण को चलाने के लिए मैंने कभी भी मूल्य नहीं लिया है।
डीन

@vwvan: हां, क्षमा करें, आपको sedइस उदाहरण में जीएनयू की आवश्यकता होगी
स्टीव

2
@ डीन: एफडब्ल्यूआईडब्ल्यू, मैं ओएसएक्स :-)
स्टीव

5
बस इसे बदल दें sed 's/./\U&/और यह POSIX sed पर काम करेगा।
डेविड कॉनरैड


14

यहाँ "मूल" पाठ उपकरण तरीका है:

#!/bin/bash

string="abcd"
first=`echo $string|cut -c1|tr [a-z] [A-Z]`
second=`echo $string|cut -c2-`
echo $first$second

अंत में एक चर के साथ और मैक पर काम करता है कि कुछ! धन्यवाद!
OZZIE

4
@DanieleOrlando, उतना पोर्टेबल नहीं जितना कि कोई उम्मीद कर सकता है। tr [:lower:] [:upper:]एक बेहतर विकल्प है अगर उसे उन भाषाओं / स्थानों में काम करने की आवश्यकता है जो उन अक्षरों को शामिल करते हैं जो a-zया A-Zश्रेणियों में नहीं हैं।
चार्ल्स डफी


4

इसे बैश-3.2 के साथ शुद्ध बैश में भी किया जा सकता है:

# First, get the first character.
fl=${foo:0:1}

# Safety check: it must be a letter :).
if [[ ${fl} == [a-z] ]]; then
    # Now, obtain its octal value using printf (builtin).
    ord=$(printf '%o' "'${fl}")

    # Fun fact: [a-z] maps onto 0141..0172. [A-Z] is 0101..0132.
    # We can use decimal '- 40' to get the expected result!
    ord=$(( ord - 40 ))

    # Finally, map the new value back to a character.
    fl=$(printf '%b' '\'${ord})
fi

echo "${fl}${foo:1}"

फू को कैसे परिभाषित करें? मैंने कोशिश की foo = $1, लेकिन मैं केवल मिल-bash: foo: command not found
Ozzie

1
@OZZIE, =असाइनमेंट में कोई स्थान नहीं है । यह कुछ ऐसा है जो shellcheck.net आपके लिए प्रोग्रामेटिक रूप से खोजेगा
चार्ल्स डफी

मैं हमेशा यह भूल जाता हूं कि शेल स्क्रिप्ट के बारे में .. केवल भाषा जहां एक स्थान (पहले / बाद) मायने रखता है ... आह (अजगर सही ढंग से कम से कम 4 है अगर मुझे सही याद है)
OZZIE

@OZZIE, यह है बात करने, अगर यह मामला नहीं था, तो आप पारित नहीं हो सका क्योंकि =एक कार्यक्रम के लिए एक तर्क के रूप (यह कैसे करता है, तो पता करने के लिए माना जाता है someprogram =चल रहा है someprogram, या नाम के एक चर करने के लिए बताए someprogram?)
चार्ल्स डफी

3

यह भी काम करता है ...

FooBar=baz

echo ${FooBar^^${FooBar:0:1}}

=> Baz
FooBar=baz

echo ${FooBar^^${FooBar:1:1}}

=> bAz
FooBar=baz

echo ${FooBar^^${FooBar:2:2}}

=> baZ

और इसी तरह।

सूत्रों का कहना है:

Inroductions / ट्यूटोरियल:


3

केवल पहले शब्द को बड़ा करने के लिए:

foo='one two three'
foo="${foo^}"
echo $foo

नी दो तीन


चर में प्रत्येक शब्द को भुनाने के लिए :

foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo

नी टी वो टी ह्री


(बाश 4+ में काम करता है)


foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done) हर शब्द के लिए छोटा संकल्प। foo नाउ "वन टू थ्री" है
vr286

मैं अपरकेस के पहले 3 या 4 अक्षरों को कैसे बड़ा कर सकता हूं? जैसा PQRS-123-v1 को PQRS-123-v1 ? या आप कह सकते हैं, पहले हाइफ़न से पहले सभी पत्र ...
विक्की देव

2

लिनक्स और ओएसएक्स दोनों के लिए वैकल्पिक और स्वच्छ समाधान, इसका उपयोग बैश चर के साथ भी किया जा सकता है

python -c "print(\"abc\".capitalize())"

एबीसी देता है


0

यह एक मेरे लिए काम किया:

वर्तमान निर्देशिका में सभी * php फ़ाइल के लिए खोज, और प्रत्येक फ़ाइल नाम के पहले अक्षर को कैपिटल लेटर में बदलें:

जैसे: test.php => Test.php

for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done

4
मूल प्रश्न एक स्ट्रिंग था, और नाम बदलने वाली फ़ाइलों का कोई संदर्भ नहीं था।
एंडीवेज़

0

बस यहाँ मज़े के लिए आप हैं:

foo="bar";    

echo $foo | awk '{$1=toupper(substr($1,0,1))substr($1,2)}1'
# or
echo ${foo^}
# or
echo $foo | head -c 1 | tr [a-z] [A-Z]; echo $foo | tail -c +2
# or
echo ${foo:1} | sed -e 's/^./\B&/'

0

बिल्कुल नहीं पूछा, लेकिन काफी मददगार

declare -u foo #When the variable is assigned a value, all lower-case characters are converted to upper-case.

foo=bar
echo $foo
BAR

और इसके विपरीत

declare -l foo #When the variable is assigned a value, all upper-case characters are converted to lower-case.

foo=BAR
echo $foo
bar

-1
first-letter-to-lower () {
        str="" 
        space=" " 
        for i in $@
        do
                if [ -z $(echo $i | grep "the\|of\|with" ) ]
                then
                        str=$str"$(echo ${i:0:1} | tr  '[A-Z]' '[a-z]')${i:1}$space" 
                else
                        str=$str${i}$space 
                fi
        done
        echo $str
}
first-letter-to-upper-xc () {
        v-first-letter-to-upper | xclip -selection clipboard
}
first-letter-to-upper () {
        str="" 
        space=" " 
        for i in $@
        do
                if [ -z $(echo $i | grep "the\|of\|with" ) ]
                then
                        str=$str"$(echo ${i:0:1} | tr  '[a-z]' '[A-Z]')${i:1}$space" 
                else
                        str=$str${i}$space 
                fi
        done
        echo $str
}

first-letter-to-lower-xc () {v-first-letter-to-lower | x -selection क्लिपबोर्ड}


-7

क्या होगा यदि पहला वर्ण अक्षर नहीं है (लेकिन एक टैब, एक स्थान और एक बची हुई दोहरी बोली)? जब तक हमें कोई पत्र नहीं मिल जाता, हम उसका बेहतर परीक्षण करेंगे ! इसलिए:

S='  \"ó foo bar\"'
N=0
until [[ ${S:$N:1} =~ [[:alpha:]] ]]; do N=$[$N+1]; done
#F=`echo ${S:$N:1} | tr [:lower:] [:upper:]`
#F=`echo ${S:$N:1} | sed -E -e 's/./\u&/'` #other option
F=`echo ${S:$N:1}
F=`echo ${F} #pure Bash solution to "upper"
echo "$F"${S:(($N+1))} #without garbage
echo '='${S:0:(($N))}"$F"${S:(($N+1))}'=' #garbage preserved

Foo bar
= \"Foo bar=

6
कृपया क्लीनर कोड लिखें! आपको सभी जगह उद्धरणों की कमी है। आप अप्रचलित वाक्यविन्यास (बैकटिक्स) का उपयोग कर रहे हैं; आप प्राचीन वाक्यविन्यास ( $[...]) का उपयोग कर रहे हैं । आप बहुत सारे बेकार कोष्ठकों का उपयोग कर रहे हैं। आप मान रहे हैं कि स्ट्रिंग में लैटिन वर्णमाला (अक्षर उच्चारण के बारे में, या अन्य वर्णमाला में अक्षरों के बारे में कैसे अक्षर हैं?)। इस स्निपेट को प्रयोग करने योग्य बनाने के लिए आपके पास बहुत काम है! (और जब से आप रेगेक्स का उपयोग कर रहे हैं, आप लूप के बजाय पहला अक्षर खोजने के लिए रेगेक्स का उपयोग कर सकते हैं)।

6
मुझे लगता है आप ग़लत हैं। यह अनिवार्य टिप्पणी है जो उत्तर के सभी गलत पैटर्न और गलतफहमी को स्पष्ट करते हुए डाउनवोट के साथ आती है। कृपया, अपनी गलतियों से सीखें (और उससे पहले, उन्हें समझने की कोशिश करें) जिद्दी होने के बजाय। एक अच्छा साथी बनना बुरी प्रथाओं को फैलाने के साथ भी असंगत है।
ग्नौरफ_ग्निउरफ

1
या, यदि बैश ,4 का उपयोग करते हैं, तो आपको आवश्यकता नहीं है tr:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
gniourf_gniourf

5
यह कोड अभी भी बुरी तरह से टूटा हुआ है। यह अभी भी आधुनिक प्रतिस्थापन सिंटैक्स के बजाय बैकटिक्स का उपयोग कर रहा है; यह अभी भी बेजोड़ उद्धरण है; यह अभी भी उन स्थानों में लापता उद्धरण है जहां वे वास्तव में बात करते हैं ; आदि कुछ व्हाट्सएप से घिरे ग्लोब कैरेक्टर को अपने टेस्ट डेटा में डालने की कोशिश करें, अगर आपको विश्वास नहीं हो रहा है कि उन गायब कोट्स में फर्क पड़ता है, और उन समस्याओं को हल करता है, जब तक यह कोड साफ नहीं हो जाता।
चार्ल्स डफी

2
भाषा के लिए जैसा कि आपने unix.stackexchange.com/questions/68694/… से उद्धृत किया है , जो आपको याद आती है, वह उस echo $fooस्थिति का एक उदाहरण है जहां पार्सर शब्दों की सूची की अपेक्षा करता है ; तो आपके में echo ${F}, सामग्री की Fस्ट्रिंग-विभाजन और ग्लोब-विस्तारित हैं। यह echo ${S:$N:1}उदाहरण और बाकी सभी के लिए समान रूप से सच है । बशपिटल्स देखें # 14
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.