बस अपने खुद के पार्सर लिखना समाप्त कर दिया। मैंने यहां पाए गए विभिन्न पार्सर का उपयोग करने की कोशिश की, कोई भी ksh93 (AIX) और बैश (लिनक्स) दोनों के साथ काम नहीं करता है।
यह पुरानी प्रोग्रामिंग शैली है - लाइन द्वारा पार्सिंग लाइन। बहुत तेज है क्योंकि यह कुछ बाहरी आदेशों का उपयोग करता है। सरणी के गतिशील नाम के लिए आवश्यक सभी eval के कारण थोड़ा धीमा।
Ini समर्थन 3 विशेष वाक्यविन्यास:
- शामिलफाइल = आईएनआई फ़ाइल -> एक अतिरिक्त आईआईएल फ़ाइल लोड करें। कई फाइलों में आईआईएन को विभाजित करने के लिए उपयोगी है, या कॉन्फ़िगरेशन के कुछ टुकड़े का फिर से उपयोग करें
- शामिल = निर्देशिका -> शामिल के रूप में ही, लेकिन एक पूरी निर्देशिका शामिल हैं
- शामिल करना = अनुभाग -> एक मौजूदा अनुभाग को वर्तमान अनुभाग में कॉपी करें।
मैं बहुत जटिल, फिर से प्रयोग करने योग्य आईएनई फाइल करने के लिए सभी थॉट्स सिंटैक्स का उपयोग करता था। नए ओएस स्थापित करते समय उत्पादों को स्थापित करने के लिए उपयोगी - हम ऐसा बहुत कुछ करते हैं।
मानों को $ {ini [$ अनुभाग। $ आइटम]} के साथ पहुँचा जा सकता है। इसे कॉल करने से पहले सरणी को परिभाषित किया जाना चाहिए।
मज़े करो। आशा है कि यह किसी और के लिए उपयोगी है!
function Show_Debug {
[[ $DEBUG = YES ]] && echo "DEBUG $@"
}
function Fatal {
echo "$@. Script aborted"
exit 2
}
#-------------------------------------------------------------------------------
# This function load an ini file in the array "ini"
# The "ini" array must be defined in the calling program (typeset -A ini)
#
# It could be any array name, the default array name is "ini".
#
# There is heavy usage of "eval" since ksh and bash do not support
# reference variable. The name of the ini is passed as variable, and must
# be "eval" at run-time to work. Very specific syntax was used and must be
# understood before making any modifications.
#
# It complexify greatly the program, but add flexibility.
#-------------------------------------------------------------------------------
function Load_Ini {
Show_Debug "$0($@)"
typeset ini_file="$1"
# Name of the array to fill. By default, it's "ini"
typeset ini_array_name="${2:-ini}"
typeset section variable value line my_section file subsection value_array include_directory all_index index sections pre_parse
typeset LF="
"
if [[ ! -s $ini_file ]]; then
Fatal "The ini file is empty or absent in $0 [$ini_file]"
fi
include_directory=$(dirname $ini_file)
include_directory=${include_directory:-$(pwd)}
Show_Debug "include_directory=$include_directory"
section=""
# Since this code support both bash and ksh93, you cannot use
# the syntax "echo xyz|while read line". bash doesn't work like
# that.
# It forces the use of "<<<", introduced in bash and ksh93.
Show_Debug "Reading file $ini_file and putting the results in array $ini_array_name"
pre_parse="$(sed 's/^ *//g;s/#.*//g;s/ *$//g' <$ini_file | egrep -v '^$')"
while read line; do
if [[ ${line:0:1} = "[" ]]; then # Is the line starting with "["?
# Replace [section_name] to section_name by removing the first and last character
section="${line:1}"
section="${section%\]}"
eval "sections=\${$ini_array_name[sections_list]}"
sections="$sections${sections:+ }$section"
eval "$ini_array_name[sections_list]=\"$sections\""
Show_Debug "$ini_array_name[sections_list]=\"$sections\""
eval "$ini_array_name[$section.exist]=YES"
Show_Debug "$ini_array_name[$section.exist]='YES'"
else
variable=${line%%=*} # content before the =
value=${line#*=} # content after the =
if [[ $variable = includefile ]]; then
# Include a single file
Load_Ini "$include_directory/$value" "$ini_array_name"
continue
elif [[ $variable = includedir ]]; then
# Include a directory
# If the value doesn't start with a /, add the calculated include_directory
if [[ $value != /* ]]; then
value="$include_directory/$value"
fi
# go thru each file
for file in $(ls $value/*.ini 2>/dev/null); do
if [[ $file != *.ini ]]; then continue; fi
# Load a single file
Load_Ini "$file" "$ini_array_name"
done
continue
elif [[ $variable = includesection ]]; then
# Copy an existing section into the current section
eval "all_index=\"\${!$ini_array_name[@]}\""
# It's not necessarily fast. Need to go thru all the array
for index in $all_index; do
# Only if it is the requested section
if [[ $index = $value.* ]]; then
# Evaluate the subsection [section.subsection] --> subsection
subsection=${index#*.}
# Get the current value (source section)
eval "value_array=\"\${$ini_array_name[$index]}\""
# Assign the value to the current section
# The $value_array must be resolved on the second pass of the eval, so make sure the
# first pass doesn't resolve it (\$value_array instead of $value_array).
# It must be evaluated on the second pass in case there is special character like $1,
# or ' or " in it (code).
eval "$ini_array_name[$section.$subsection]=\"\$value_array\""
Show_Debug "$ini_array_name[$section.$subsection]=\"$value_array\""
fi
done
fi
# Add the value to the array
eval "current_value=\"\${$ini_array_name[$section.$variable]}\""
# If there's already something for this field, add it with the current
# content separated by a LF (line_feed)
new_value="$current_value${current_value:+$LF}$value"
# Assign the content
# The $new_value must be resolved on the second pass of the eval, so make sure the
# first pass doesn't resolve it (\$new_value instead of $new_value).
# It must be evaluated on the second pass in case there is special character like $1,
# or ' or " in it (code).
eval "$ini_array_name[$section.$variable]=\"\$new_value\""
Show_Debug "$ini_array_name[$section.$variable]=\"$new_value\""
fi
done <<< "$pre_parse"
Show_Debug "exit $0($@)\n"
}