बैश गेटॉप्स, पार्सिंग पर्वतमाला


0

गेटॉप का उपयोग करते हुए तर्क मान श्रेणी को पार्स करने के लिए सबसे अच्छा तरीका क्या होगा ? उदहारण के लिए:

$ script.sh -r2-4,6,8-10-10

मेरी स्क्रिप्ट में मैं तब 2, 3, 4, 6, 8, 9 और 10 के मान के साथ एक सरणी होगा।


1
मेरे पास गेटअप के साथ कोई अनुभव नहीं है, लेकिन यदि आप बैश का उपयोग कर रहे हैं, तो पहले सीमा का विस्तार क्यों नहीं किया जाता है, जैसे {2..4}?
slhck

ऐसा कभी नहीं सोचा था, यह बहुत अच्छी तरह से काम करता है। एक समस्या यह है कि मुझे कई विकल्पों का उपयोग करना होगा: -r {2..4} -r6 -r {8..10}।
c0dem4gnetic

@ भार्गव भट आप गलत से जुड़े getopt(3), जो कि जैसा है वैसा नहीं है getopt(1)
slhck

@ श्लोक: उफ़! अब ठीक किया गया है
भार्गव भाट

जवाबों:


1

यदि आप दोनों का उपयोग करना चाहते हैं -r ..., .. और -r ... -r ... -r ...: इस तरह के रूप में एक स्क्रिप्ट बनाएँ "toto.bash":

#!/usr/bin/bash

    add_ranges () #this will add each integers or ranges (a-b) into the array: myarray
    {
       #first we test that we only have those validchars (makes the second step below much easier to write)
       validchars='[1234567890,-]'
       echo "$@" | grep "${validchars}" >/dev/null && {
          : ; #only valid chars, probably ok. (but could be wrong, ex: 1-  2,, 4-3  etc...)
       } || {
          echo "The ranges you entered are not valid : they should only contain such characters: ${validchars}"
          exit 1 ;
       }
       #secondly we now try to handle the current ranges lists (comma separated)
       for range in $(echo "${@}" | tr ',' ' ')
       do
          if   [[ ${range} =~ ^[0-9]+$ ]]     # [[ can handle regexp matching, and doesn't need to quote parameters
          then
             myarray[${#myarray[*]}]=${range}  #add this after the latest element in myarray
          elif [[ ${range} =~ ^[0-9]+-[0-9]+$ ]]
          then
             newrange=$(echo "$range" | sed -e 's/-/../')
             for i in `eval echo {$newrange}` # {a..b} means: all integers a to b
             do
                myarray[${#myarray[*]}]=${i}  #add this after the latest element in myarray
             done
          else
             echo "ERROR: I can not recognize this range: $range"
             exit 1
          fi
       done
    }

   ###### handle options using getopts:
   OPTIND=1; #here for compatibility's sake: in case you add another function that uses getopts, reminds you to re-set OPTIND each time.
   while getopts "r:" zeoption; do
      case $zeoption in
         r)
        allranges="${OPTARG}";
            add_ranges "${OPTARG}";
            ;;
         -)
        echo "option --, OPTARG=$OPTARG";
            break ;
            ;;
         *)
        echo "ERROR: Unrecognized option: zeoption=$zeoption OPTARG=$OPTARG";
            shift
            ;;
      esac;
   done;

   shift $((OPTIND-1)) ; #we shift away all the options we processed.
   ###### end of options handling

    # and we continue here...

   echo "we now have : remaining arguments: ${@}"
   echo "and myarray contains: ${myarray[@]}"

और फिर इसे चलाएं:

$ ./toto.bash -r 2,4,6-12 -r 100-103 foo bar
we now have : remaining arguments: foo bar
and myarray contains: 2 4 6 7 8 9 10 11 12 100 101 102 103

मैं सिर्फ संकेत देना चाहता था, लेकिन यह कहना कि इसे लिखना बेहतर है। यह लंबे उत्तर के लिए बनाता है, लेकिन मुझे आशा है कि यह मदद करता है!


प्रतिभाशाली! स्क्रिप्ट में टिप्पणियों को जोड़ने के लिए धन्यवाद इसके बाद का पालन करना आसान है!
c0dem4gnetic

आपका स्वागत है। कुछ हिस्सों को टिप्पणियों की आवश्यकता हो सकती है, इसलिए यदि आपके पास इस या मेरे द्वारा लिखे गए तरीके के बारे में प्रश्न हैं, तो कृपया पूछें।
ओलिवियर डुलैक

मैंने "एलिफ़" को ठीक किया ताकि हम जो भी उम्मीद करते हैं वह निकट से मेल खाता हो (अन्यथा इसमें पहले और बाद के अतिरिक्त अवांछित चरित्र शामिल हो सकते हैं)
ओलिवियर दुलैक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.