कैसे एक स्ट्रिंग में एक शब्द के सूचकांक को खोजने के लिए बैश में?


10

बैश स्क्रिप्ट में,

मेरे पास एक स्ट्रिंग है जिसमें एक या एक से अधिक स्थानों द्वारा अलग किए गए कई शब्द हैं। अर्थात:

Name   Age Sex  ID         Address

यदि मैं किसी भी शब्द को ढूंढना चाहता हूं, उदाहरण के लिए मैं "आयु" शब्द का सूचकांक ढूंढना चाहता हूं, तो मैं यह कैसे कर सकता हूं?

क्या कोई ऐसा आदेश है जो सीधे मेरे द्वारा इच्छित शब्द की अनुक्रमणिका संख्या लौटाएगा?

धन्यवाद।


क्या घोल को कड़ाई में डालना है? या जाग, grep, आदि का उपयोग किया जा सकता है?
जफ्तागा

जवाबों:


12

बैश अपने आप में सभी में बंटवारे शब्द का प्रदर्शन करता है - वास्तव में, अधिक बार नहीं, इससे बचना एक मुद्दा है, और उद्धृत करने का कारण इतना महत्वपूर्ण है। आपके मामले में इसका लाभ उठाना आसान है: बस अपने स्ट्रिंग को एक उद्धरण के बिना एक सरणी में डालें - बैश अलग-अलग तत्वों को अलग करने के लिए शब्द विभाजन का उपयोग करेगा। मान लें कि आपकी स्ट्रिंग चर में संग्रहीत है $str,

ar=($str) # no quotes!

5 तत्वों की एक सरणी लौटाएगा। आपका ऐरे इंडेक्स आपका वर्ड इंडेक्स है (0 से गिनती, जैसे अधिकांश स्क्रिप्टिंग और प्रोग्रामिंग भाषाओं में), अर्थात "आयु" का उपयोग किया जाता है

${ar[1]}  # 0 => Name, 1 => Age, 2 => Sex, 3 => ID, 4 => Address

या, यदि आपको सामग्री द्वारा तत्व सूचकांक खोजने की आवश्यकता है, तो सरणी पर लूप, अर्थात

function el_index {
    cnt=0; for el in "${ar[@]}"; do
        [[ $el == "$1" ]] && echo $cnt && break
        ((++cnt))
    done
}
el_index "Age" # => 1

वाह ... मुझे नहीं पता था कि उद्धरण के बिना तो यह एक सरणी होगी। धन्यवाद!
G3Y

4
$ export FOO="Name   Age Sex  ID         Address"

बदलें * आयु के साथ आयु - यह "आयु" से पहले कुछ भी हटा देगा:

$ echo ${FOO/*Age/Age}
Age Sex ID Address

"आयु" से पहले कुछ भी प्राप्त करें

$ echo ${FOO/Age*/}
Name

उस स्ट्रिंग की लंबाई प्राप्त करें (जो "आयु" का सूचकांक है):

$ BEGIN=${FOO/Age*/}
$ echo ${#BEGIN}
7

इस सवाल का जवाब नहीं है, लेकिन वाह! चालाक चाल। यह राख में भी काम करता है, और एम्बेडेड वेरिएबल के साथ: export L='debug info warn error'; export GTE='warn'; echo ${L/*${GTE}/${GTE}}'वॉर्न एरर' प्रिंट करता है
स्टीव टावर

0

यदि आपको बैश का सख्ती से उपयोग करने की आवश्यकता नहीं है, लेकिन आमतौर पर बैश के साथ सिस्टम पर पाए जाने वाले अन्य कार्यक्रमों का उपयोग कर सकते हैं तो आप कुछ इस तरह का उपयोग कर सकते हैं:

echo "Name   Age Sex ID  Addr" | python -c 'print(raw_input().index("Age"))+1'

पायथन शुरू होता है यह शून्य पर स्ट्रिंग इंडेक्सिंग है, इसलिए मैंने कमांड के अंत में +1 जोड़ा।


0

आप बैश के देशी रेगेक्स का उपयोग कर सकते हैं

# a function to print the index of a field and its name
printIx() { 
  for ((l=0,i=1;i<$1;i++)) ;do 
     ((l+=${#BASH_REMATCH[i]}))
  done
  printf '%3s %s\n' $l "$2"
}

#   Using a zero based index
#   "0----+----1----+----2----+----3----+----4"
str="  Name   Age Sex  ID         Address   "

if [[ $str =~ ^(\ *)(Name)(\ +)(Age)(\ +)(Sex)(\ +()ID)(\ +)(Address)\ *$ ]] ;then
  F=(Name Age Sex ID Address)
  f=(   2   4   6  8      10)  # regex back-references
  for ((g=0;g<${#f[@]};g++)) ;do
     printIx  ${f[g]} "${F[g]}"
  done 
fi

उत्पादन

  2 Name
  9 Age
 13 Sex
 20 ID
 29 Address

0

नोट : यहां यह मानकर कि इंडेक्स के माध्यम से आप यह जानना चाहते हैं कि यह कौन सा शब्द है (0 से शुरू), न कि कौन सा अक्षर स्ट्रिंग में शब्द शुरू होता है। अन्य उत्तर उत्तर को संबोधित करते हैं।

ऐसा नहीं है कि मुझे पता है, लेकिन आप एक बना सकते हैं। दो तरकीबें:

  1. निर्माण के लिए जन्मजात क्षमताओं का उपयोग व्हॉट्सएप द्वारा एक अनछुए इनपुट को विभाजित करने के लिए करें
  2. उस मामले को संभालें जहां आप अपने इच्छित कॉलम को नहीं ढूंढ सकते। इस मामले में, मैंने पाया सूचकांक को स्टाउट पर भेजने के लिए चुना और स्टेटस कोड को यह संकेत देने दिया कि क्या वह सफल था। अन्य संभावनाएं हैं।

कोड:

#!/bin/bash
find_index() {
    local str=$1
    local search=$2
    let local n=0
    local retval=1 # here, 1 is failure, 0 success
    for col in $str; do # $str unquoted -> whitespace tokenization!
    if [ $col = $search ]; then
        echo $n
        retval=0
        break
    else
        ((n++))
    fi
    done
    return $retval
}

test="Name   Age Sex  ID         Address"
idx=`find_index "$test" Age`
if [ $? -ne 0 ]; then
    echo "Not found!"
else
    echo "Found: $idx"
fi

0

शेल में निम्नलिखित जावास्क्रिप्ट ऑनलाइनर आज़माएं (जावास्क्रिप्ट शेल का उपयोग करें):

$ js <<< "x = 'Name   Age Sex  ID         Address'; print(x.indexOf('Age'));"
7

या यहाँ एक डॉक्टर के साथ:

js <<EOF
x = 'Name   Age Sex  ID         Address';
print(x.indexOf('Age'));
EOF

0

मुझे एक समाधान मिला जो ठीक काम करता है।

$ स्ट्रिंग = 'अब समय आ गया है'
$ buf = $ {स्ट्रिंग # *}
$ गूंज $ buf
समय: उत्पादन
- $ सूचकांक = $ ($ {# buf} + 1) ($ {# स्ट्रिंग})
$ इको $ इंडेक्स
आउटपुट: 8 -> पहले शब्द का सूचकांक "द"

यह जावा में फ़ंक्शन इंडेक्सऑफ () के समान काम करता है जो इनपुट स्ट्रिंग की पहली घटना देता है।

इस समाधान को यहां देखें http://www.linuxquestions.org/questions/linux-newbie-8/bash-string-manipulation-help-670627/ (अंतिम पोस्ट)। इस आदमी ने मेरा दिन बचाया। उसे श्रेय।

यदि आप पहले अनुक्रमणिका से सबस्ट्रिंग करना चाहते हैं तो तेज़ तरीका।

$ a = "कुछ लंबी स्ट्रिंग"
$ b = "ri"
$ इको $ {a / * $ b / $ b}
रिंग
$ इको $ {a / $ b * / $ b}
कुछ लॉन्ग स्ट्रिप

/programming/10349102/shell-script-substring-from-first-indexof-substring


0

यदि कोरुटाइल उपलब्ध हैं तो आप इसे निम्न तरीके से कर सकते हैं:

गूंज $ {str / आयु //} | cut -d / -f1 | wc -w

MariusMatutiae प्रति अनुरोध मैं एक स्पष्टीकरण जोड़ रहा हूं कि यह 3 चरणों का संचालन कैसे काम करता है:

गूंज $ {str / आयु //} 1. बदलें स्ट्रिंग जो अद्वितीय चार के लिए खोज की जा रही है (मेरे मामले में /)

cut -d / -f1 2. स्ट्रिंग के पूरे हिस्से को काट दें जो अद्वितीय चार के बाद है

wc -w 3. गिनती और प्रिंट शब्द जो इसे छोड़ दिया जाता है, हमें एक इंडेक्स नंबर देगा

संदर्भों के लिए कृपया देखें:

http://www.tldp.org/LDP/abs/html/parameter-substitution.html (पर जाएं: "परिवर्तनीय विस्तार / प्रतिस्थापन प्रतिस्थापन")
http://www.gnu.org/software/coreutils/manual/coreutils .html (पर जाएँ: "कट कमांड" और "wc मंगलाचरण"


जबकि यह समस्या को हल करता है, इस तरह के जवाब इन साइटों पर दिए गए हैं। यह कुछ शब्दों को खर्च करने के लिए अधिक उपयोगी होगा जो यह बताता है कि यह क्यों काम करता है। कृपया ऐसा करो।
मारियसमैटुटिया

0

दो पहले दिए गए उत्तरों का मिश्रण, शुद्ध बैश सरणियों और प्रतिस्थापन प्रतिस्थापन का उपयोग करते हुए।

विचार यह है कि आप जो चाहते हैं उससे पहले सभी शब्दों की एक स्ट्रिंग प्राप्त करें, फिर उस एरे में इसे बनाकर शब्दों की संख्या गिनें।

$ haystack="Name   Age Sex  ID         Address"
$ words_before=( ${haystack%Age*} )     # truncate string, make array
$ echo ${#words_before[*]}              # count words in array
1

बेशक आयु को दूसरे चर में संग्रहीत किया जा सकता है needle, फिर उपयोग करें ${haystack%$needle*}। समस्याओं की अपेक्षा करें यदि आप जिस शब्द को खोजते हैं वह दूसरे शब्द का एक सबसेट है, जिस स्थिति में कोप्सिएके का जवाब अभी भी काम कर रहा है।


0

यह एक 7-वर्षीय प्रश्न है, लेकिन कुछ को शुद्ध बैश में उत्तर की आवश्यकता हो सकती है।

STRING="Name   Age Sex  ID         Address"
INDEXOF_AGE=${#${STRING/Age*/}}
echo $INDEXOF_AGE
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.