আমি কীভাবে শেল স্ক্রিপ্টের মধ্যে কোনও আইএনআই মান ধরব?


104

আমার কাছে প্যারামিটার.আইএনআই ফাইল রয়েছে যেমন:

[parameters.ini]
    database_user    = user
    database_version = 20110611142248

আমি ব্যাশ শেল স্ক্রিপ্টের মধ্যে থেকে প্যারামিটার.আইএনআই ফাইলটিতে বর্ণিত ডাটাবেস সংস্করণটি পড়তে এবং ব্যবহার করতে চাই যাতে আমি এটি প্রক্রিয়া করতে পারি।

#!/bin/sh    
# Need to get database version from parameters.ini file to use in script    
php app/console doctrine:migrations:migrate $DATABASE_VERSION

আমি এই কিভাবে করব?


4
এগুলির কোনও উত্তর কি আদৌ বিভাগকে সম্মান করে?
ম্যানুয়েলস্কিনিড

উত্তর:


86

কীভাবে সেই লাইনের জন্য গ্রেপিং করা যায় তারপরে awk ব্যবহার করা

version=$(awk -F "=" '/database_version/ {print $2}' parameters.ini)

6
এতে '=' এর পরে স্থানগুলি অন্তর্ভুক্ত থাকবে।

11
স্পেসগুলি ছাঁটাই করতে, | tr -d ' 'শেষে যুক্ত করুন।
কেনারব

23
এটি আসলেই ভাল সমাধান নয়। প্রত্যেকের একটি 'ডাটাবেস_ভার্সন' ভেরিয়েবলের সাথে ২ [পরামিতি.আইআই] বিভাগ থাকার কথা ভাবুন। আপনি তখন দ্বিগুণ মান পাবেন।
নারডোক

4
হ্যাঁ দয়া করে ক্রুডিনিয়ের মতো একটি বিশেষায়িত আইএন পার্সার বিবেচনা করুন, কারণ উপরে অনেকগুলি প্রান্তের মামলাগুলি পরিচালনা করে না
পিক্সেলবিট

4
বেসিক আইএনআই ফাইলগুলির জন্য এখনও দরকারী এবং দ্রুত।
সিরিল এন।

57

Ini মানগুলি ব্যাখ্যার জন্য আপনি বাশ নেটিভ পার্সার ব্যবহার করতে পারেন, এর দ্বারা:

$ source <(grep = file.ini)

নমুনা ফাইল:

[section-a]
  var1=value1
  var2=value2
  IPS=( "1.2.3.4" "1.2.3.5" )

এক্সেস ভেরিয়েবল করার জন্য, আপনাকে কেবল তাদের মুদ্রণ: echo $var1। উপরে বর্ণিত হিসাবে আপনি অ্যারে ব্যবহার করতে পারেন ( echo ${IPS[@]})।

আপনি যদি কেবল একটি মান চান তবে এটির জন্য গ্রেপ করুন:

source <(grep var1 file.ini)

ডেমো জন্য, asciinema এই রেকর্ডিং পরীক্ষা

এটি সহজ কারণ আপনার কোনও বাহ্যিক লাইব্রেরির ডেটা বিশ্লেষণের প্রয়োজন নেই, তবে এটি কিছু অসুবিধাগুলি সহ আসে। উদাহরণ স্বরূপ:

  • যদি আপনার =(ভেরিয়েবল নাম এবং মান) এর মধ্যে শূণ্যস্থান থাকে তবে আপনাকে প্রথমে স্পেসগুলি ট্রিম করতে হবে, যেমন

      $ source <(grep = file.ini | sed 's/ *= */=/g')
    

    অথবা আপনি যদি ফাঁকা জায়গাগুলি (মাঝখানে সহ) সম্পর্কে চিন্তা না করেন তবে ব্যবহার করুন:

      $ source <(grep = file.ini | tr -d ' ')
    
  • ;মন্তব্যগুলি সমর্থন করতে , এগুলি এর সাথে প্রতিস্থাপন করুন #:

      $ sed "s/;/#/g" foo.ini | source /dev/stdin
    
  • বিভাগগুলি সমর্থিত নয় (উদাহরণস্বরূপ যদি আপনি থাকেন [section-name]তবে এটি grep =অপ্রত্যাশিত ত্রুটির জন্য একইভাবে ফিল্টার করে ফেলতে হবে, যেমন )।

    আপনি নির্দিষ্ট অধ্যায়, ব্যবহার অধীনে সুনির্দিষ্ট মানের পড়া করার প্রয়োজন হলে grep -A, sed,awk বাex )।

    যেমন

      source <(grep = <(grep -A5 '\[section-b\]' file.ini))
    

    দ্রষ্টব্য: -A5বিভাগটিতে পড়ার জন্য সারিগুলির সংখ্যা কোথায় । ডিবাগের sourceসাথে প্রতিস্থাপন করুন cat

  • যদি আপনার কোনও পার্সিং ত্রুটি হয় তবে এগুলি যুক্ত করে এড়িয়ে যান: 2>/dev/null

আরো দেখুন:


4
তবে ... source <(grep = <(grep -A5 '\[section-b\]' file.ini))এটি এর জন্য কার্যকর হবে না: [সেকেন্ড এ] এ = 1 বি = 2 সি = 3 [সেকেন্ড বি] এ = 2 বি = 3 [সেকেন্ড গ] a = 0। যেখানে লাইনগুলির সাথে কোনও সুনির্দিষ্ট নিয়ম নেই
সাইকোজোজিক

আমি উত্সটি ব্যবহার করার চেষ্টা করেছি, তবে আমি যখন $ var1 প্রতিধ্বনিত করি তখন এটি কিছুই দেয় না। কেন?
উঃ

@ এজিএইচ আমি নিশ্চিত নই, আমার পক্ষে কাজ করে। আপনি বাশ শেল ব্যবহার করছেন তা নিশ্চিত করুন। দেখুন: asciinema.org/a/306481
কেনারব

এটি মার্জিত হত তবে এটি ওএস এক্স (ক্যাটালিনা) এ কাজ করতে ব্যর্থ হয়েছে। এটি zsh (বর্তমান ডিফল্ট শেল) কমান্ড প্রম্পট থেকে কাজ করে, তবে একবার আমি এটি কোনও স্ক্রিপ্টে রেখে দিলে ত্রুটিটি পাই syntax error near unexpected token '('। বাশ সহ, এটি নীরবে প্রম্পট এবং স্ক্রিপ্ট উভয়ই ব্যর্থ হয়।
মিআরিন

30

বাশ এই ফাইলগুলির জন্য কোনও পার্সার সরবরাহ করে না। স্পষ্টতই আপনি একটি অর্ডিক কমান্ড বা কয়েকটি কল কল ব্যবহার করতে পারেন তবে আপনি যদি বাশ-পুরোহিত হয়ে থাকেন এবং অন্য কোনও শেল ব্যবহার করতে না চান তবে আপনি নিম্নলিখিত অস্পষ্ট কোডটি চেষ্টা করতে পারেন:

#!/usr/bin/env bash
cfg_parser ()
{
    ini="$(<$1)"                # read the file
    ini="${ini//[/\[}"          # escape [
    ini="${ini//]/\]}"          # escape ]
    IFS=$'\n' && ini=( ${ini} ) # convert to line-array
    ini=( ${ini[*]//;*/} )      # remove comments with ;
    ini=( ${ini[*]/\    =/=} )  # remove tabs before =
    ini=( ${ini[*]/=\   /=} )   # remove tabs after =
    ini=( ${ini[*]/\ =\ /=} )   # remove anything with a space around =
    ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix
    ini=( ${ini[*]/%\\]/ \(} )    # convert text2function (1)
    ini=( ${ini[*]/=/=\( } )    # convert item to array
    ini=( ${ini[*]/%/ \)} )     # close array parenthesis
    ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick
    ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
    ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
    ini[0]="" # remove first element
    ini[${#ini[*]} + 1]='}'    # add the last brace
    eval "$(echo "${ini[*]}")" # eval the result
}

cfg_writer ()
{
    IFS=' '$'\n'
    fun="$(declare -F)"
    fun="${fun//declare -f/}"
    for f in $fun; do
        [ "${f#cfg.section}" == "${f}" ] && continue
        item="$(declare -f ${f})"
        item="${item##*\{}"
        item="${item%\}}"
        item="${item//=*;/}"
        vars="${item//=*/}"
        eval $f
        echo "[${f#cfg.section.}]"
        for var in $vars; do
            echo $var=\"${!var}\"
        done
    done
}

ব্যবহার:

# parse the config file called 'myfile.ini', with the following
# contents::
#   [sec2]
#   var2='something'
cfg.parser 'myfile.ini'

# enable section called 'sec2' (in the file [sec2]) for reading
cfg.section.sec2

# read the content of the variable called 'var2' (in the file
# var2=XXX). If your var2 is an array, then you can use
# ${var[index]}
echo "$var2"

পুরাতন স্কুল ডিভোপস ব্লগ সাইটে বাশ ইনি-পার্সার পাওয়া যাবে ।


4
যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত পৃষ্ঠাগুলি পরিবর্তিত হলে লিঙ্ক-শুধুমাত্র উত্তরগুলি অবৈধ হতে পারে।
অ্যালেক্সেক্স

8
আমি সাধারণত সেই মতামত দিচ্ছি; কেবলমাত্র আমি বলতে পারি যে আমি যুবক এবং বোকা :-)
ফ্রেড্রিক পাইহল

4
আপনি যদি এই স্নিপেটটি পছন্দ করেন, github.com/albfan/bash-ini-parser
albfan

4
সঠিকভাবে কাজ করতে, cfg.parser এর পরিবর্তে cfg_parser ব্যবহার করা দরকার
ওয়েস

4
TYPO: "cfg.parser" হওয়া উচিত "cfg_parser"।
সেটআপ করুন

29

সেড ওয়ান-লাইনার, যা বিভাগগুলিকে অ্যাকাউন্টে নেয়। উদাহরণ ফাইল:

[section1]
param1=123
param2=345
param3=678

[section2]
param1=abc
param2=def
param3=ghi

[section3]
param1=000
param2=111
param3=222

বলুন আপনি বিভাগ 2 থেকে পরম 2 চান। নিম্নলিখিত চালান:

sed -nr "/^\[section2\]/ { :l /^param2[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" ./file.ini

তোমাকে দিবে

def

4
সেড-এনআর "/ ^ \ [সেকশন ২ \] / {: l /^\s* ^াবলম্বন :) [SECTION2] এবং # হ্যাশ-স্টাইলের মন্তব্য লাইনের সাথে একটি .conf শৈলী ফাইলের জন্য মন্তব্য ছাড়াই। তারপরে প্যারামਨਾਮটির জন্য গ্রেপ করুন যদি আপনি কেবল একটি প্যারামিটার চান।
গাওথে

পরবর্তী লাইনগুলি পড়ার চেয়ে সেড রেঞ্জের ঠিকানাগুলি আরও ভাল ব্যবহার করুন:"/^\[section2\]/,/^\[/{...}"
বেসিন

4
যদি কোনও brew install gnu-sedgsedsed: illegal option -- r
ম্যাকে থাকে

sed -nr "/^\[SECTION2\]/ { :l /^\s*[^#].*/ p; n; /^\[/ q; b l; }" অভিব্যক্তি কীভাবে কাজ করে তা দয়া করে কেউ ব্যাখ্যা করতে পারেন ? আপনাকে ধন্যবাদ
foo_l

21

কেবল আপনার .ini ফাইলটিকে ব্যাশ বডিতে অন্তর্ভুক্ত করুন:

ফাইল example.ini :

DBNAME=test
DBUSER=scott
DBPASSWORD=tiger

ফাইল উদাহরণ.শ

#!/bin/bash
#Including .ini file
. example.ini
#Test
echo "${DBNAME}   ${DBUSER}  ${DBPASSWORD}"

4
এটি নির্বাচিত উত্তর হওয়া উচিত। এটি file.properties নিয়ে কাজ করে এবং ফল্ট সহনশীল (ভিতরে ফাঁকা লাইন সহ ফাইল)। ধন্যবাদ
অ্যান্টনি

21
আইএনআই ফাইলগুলির [বিভাগ] অংশটি পরিচালনা করে না।
সেটআপ করুন

এটি সেরা উত্তর!
জাভাশেরিফ 16'8

17
আশা করি কেউ
ইনআই

4
সাব-শেলের মধ্যে অনেক বেশি নিরাপদ: $ (। উদাহরণ.inii; প্রতিধ্বনি $ ডিবিএনএম)
ধনী রিমার

14

আমি এখনও অবধি যে সমস্ত সমাধান দেখেছি সেগুলিও মন্তব্য করা লাইনে মন্তব্য করেছে। মন্তব্য কোডটি হ'ল এটি একটি নয় ;:

awk -F '=' '{if (! ($0 ~ /^;/) && $0 ~ /database_version/) print $2}' file.ini

4
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত ক) এটি লাইনগুলিতে মন্তব্য করা হ্যান্ডলগুলি খ) সাধারণ :)
সুদার

4
এটি ভয়াবহ, আপনি @ পেঙ্গুইনলাস্ট! ব্যবহার: 1. সেমিকোলন উপসর্গের সাথে সম্পূর্ণ-লাইন মন্তব্য অনুমোদিত (লাইন মন্তব্যের অন্তর্নিহিত শেষের অনুমতি নেই); ২.উইটস্পেসটি ফলাফল থেকে পৃথক নয় (সুতরাং যদি আইএনআই ফাইলটিতে 'a = 1' থাকে তবে স্ক্রিপ্টটির অনুসন্ধান 'এ' এর জন্য '1' এর মূল্যায়ন হয়)।
অ্যানিএগাইল

4
স্পেসগুলি ছাঁটাই করতে, | tr -d ' 'শেষে যুক্ত করুন।
কেনারব

প্রস্তাবিত উত্তরের মতো একই সমস্যা রয়েছে; এটি "
ডাটাবেস_দলীয়করণ

12

আরও সম্ভাব্য সমাধানগুলির মধ্যে একটি

dbver=$(sed -n 's/.*database_version *= *\([^ ]*.*\)/\1/p' < parameters.ini)
echo $dbver

8

ইন-স্টাইলের আমার_ফাইলে আমার_কিটির মান প্রদর্শন করুন :

sed -n -e 's/^\s*my_key\s*=\s*//p' my_file
  • -n - ডিফল্ট হিসাবে কিছু মুদ্রণ করবেন না
  • -e - এক্সপ্রেশন কার্যকর
  • s/PATTERN//p - প্যাটার্নে এই প্যাটার্ন অনুসরণ করে কিছু প্রদর্শন করুন:
  • ^ - প্যাটার্নটি লাইনের শুরুতে শুরু হয়
  • \s - সাদা স্থানের অক্ষর
  • * - শূন্য বা অনেকগুলি (সাদা স্থানের অক্ষর)

উদাহরণ:

$ cat my_file
# Example INI file
something   = foo
my_key      = bar
not_my_key  = baz
my_key_2    = bing

$ sed -n -e 's/^\s*my_key\s*=\s*//p' my_file
bar

সুতরাং:

একটি প্যাটার্ন সন্ধান করুন যেখানে লাইনটি শূন্য বা অনেকগুলি শ্বেতস্পেস অক্ষর দিয়ে শুরু হয়, তারপরে মাই_কি স্ট্রিং পরে শূন্য বা অনেকগুলি শ্বেতস্পেস অক্ষর, সমান চিহ্ন, তারপরে শূন্য বা অনেকগুলি সাদা স্পেস অক্ষর রয়েছে again সেই প্যাটার্ন অনুসরণ করে সেই লাইনে থাকা বাকী সমস্ত সামগ্রী প্রদর্শন করুন।


আপনার উদাহরণটি কাজ করে না ( barমুদ্রিত নয় ), কমপক্ষে ইউনিক্স / ওএসএক্স এ।
কেনারব

7

অন্যান্য পাইথন জবাবগুলির মতো, আপনি -cকমান্ড লাইনে প্রদত্ত পাইথন স্টেটমেন্টগুলির ক্রম সম্পাদন করতে পতাকা ব্যবহার করে এটি করতে পারেন :

$ python3 -c "import configparser; c = configparser.ConfigParser(); c.read('parameters.ini'); print(c['parameters.ini']['database_version'])"
20110611142248

এটিতে কেবল পাইথন স্ট্যান্ডার্ড লাইব্রেরি প্রয়োজন এবং একটি পৃথক স্ক্রিপ্ট ফাইল না লেখার সুবিধা রয়েছে।

বা আরও ভাল পাঠযোগ্যতার জন্য এখানে একটি নথি ব্যবহার করুন, এইভাবে:

#!/bin/bash
python << EOI
import configparser
c = configparser.ConfigParser()
c.read('params.txt')
print c['chassis']['serialNumber']
EOI

serialNumber=$(python << EOI
import configparser
c = configparser.ConfigParser()
c.read('params.txt')
print c['chassis']['serialNumber']
EOI
)

echo $serialNumber

যদি আমি এই কমান্ডটি ব্যবহার করে অ্যারে হিসাবে পুরো বিভাগটি দখল করতে চাই?
দেবোপাম পারুয়া

7

সেড

আপনি sedini কনফিগারেশন ফাইলটি পার্স করতে ব্যবহার করতে পারেন , বিশেষত যখন আপনি বিভাগের নামগুলি পছন্দ করেন:

# last modified 1 April 2001 by John Doe
[owner]
name=John Doe
organization=Acme Widgets Inc.

[database]
# use IP address in case network name resolution is not working
server=192.0.2.62
port=143
file=payroll.dat

সুতরাং sedউপরের ডেটা পার্স করতে আপনি নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করতে পারেন :

# Configuration bindings found outside any section are given to
# to the default section.
1 {
  x
  s/^/default/
  x
}

# Lines starting with a #-character are comments.
/#/n

# Sections are unpacked and stored in the hold space.
/\[/ {
  s/\[\(.*\)\]/\1/
  x
  b
}

# Bindings are unpacked and decorated with the section
# they belong to, before being printed.
/=/ {
  s/^[[:space:]]*//
  s/[[:space:]]*=[[:space:]]*/|/
  G
  s/\(.*\)\n\(.*\)/\2|\1/
  p
}

এটি আইআইটি ডেটা এই ফ্ল্যাট ফর্ম্যাটে রূপান্তরিত করবে:

owner|name|John Doe
owner|organization|Acme Widgets Inc.
database|server|192.0.2.62
database|port|143
database|file|payroll.dat

সুতরাং ব্যবহার করে sed, awkবা readপ্রতিটি লাইনে বিভাগের নাম রেখে পার্স করা আরও সহজ হবে ।

ক্রেডিট এবং উত্স: শেল স্ক্রিপ্টগুলির জন্য কনফিগারেশন ফাইলগুলি , মাইকেল গ্রেনওয়াল্ড


বিকল্পভাবে, আপনি এই প্রকল্পটি ব্যবহার করতে পারেন chilladx/config-parser:, একটি কনফিগারেশন পার্সার ব্যবহার করে sed


এটা অসাধারণ! আমি এটির মতো চ্যাপ্টা করার কথা ভাবছিলাম তবে এটি আমি একসাথে হ্যাক করতে যাচ্ছিলাম তার বাইরে কয়েক মাইল দূরে!
গ্রিঞ্চ

6

crudiniআইএনআই মান পেতে আপনি সরঞ্জাম ব্যবহার করতে পারেন , যেমন:

DATABASE_VERSION=$(crudini --get parameters.ini '' database_version)

লক্ষ্য করুন এটি পাইথন ভিত্তিক, তাই এমবেডেড লিনাক্স অ্যাপ্লিকেশনগুলির জন্য উপযুক্ত নাও হতে পারে।
ক্রেগ ম্যাককুইন

এটি স্ট্যান্ডার্ড ফেডোরা রিপোর অংশ (31 সহ পরীক্ষিত)। yum install crudini
শ্রুউমাউস

5

লোকেরা (আমার মতো) শেল স্ক্রিপ্ট থেকে INI ফাইলগুলি পড়ার জন্য সন্ধান করছে (শেল পড়ুন, বাশ নয়) - আমি একটি সামান্য সহায়ক সহায়ক লাইব্রেরি ছুঁড়েছি যা ঠিক এটি করার চেষ্টা করে:

https://github.com/wallyhall/shini (এমআইটি লাইসেন্স, আপনার খুশি হিসাবে এটি করুন। কোডটি বেশ দীর্ঘ হওয়ায় আমি এটিকে ইনলাইন সহ উপরে সংযুক্ত করেছি))

এটি sedউপরে প্রস্তাবিত সরল রেখাগুলির চেয়ে কিছুটা "জটিল" - তবে খুব অনুরূপ ভিত্তিতে কাজ করে।

ফাংশন একটি ফাইল-লাইন-এ-লাইনে পড়ে - বিভাগ চিহ্নিতকারী ( [section]) এবং কী / মান ঘোষণা ( key=value) for

শেষ পর্যন্ত আপনি নিজের ফাংশনে একটি কলব্যাক পাবেন - বিভাগ, কী এবং মান।


@ ক্রেইগম্যাককিউন - আমি আজ রাতে খুব আলফা-মানের কিছু লেখার সমর্থন যুক্ত করেছি। এটি কোনও কল্পনা দ্বারা "সম্পূর্ণ" নয়!
ওলি

উজ্জ্বল! :-) মেজর
জোনাথন

2

কিছু উত্তর মন্তব্য সম্মান করে না। কেউ কেউ বিভাগকে সম্মান করেন না। কেউ কেউ কেবল একটি বাক্য গঠন (কেবল ":" বা কেবল "=") সনাক্ত করে। কিছু পাইথন উত্তর আমার মেশিনে ব্যর্থতার কারণে ক্যাপিটালাইজেশন বা সিএস মডিউলটি আমদানি করতে ব্যর্থ হওয়ার কারণে ব্যর্থ হয়। সব কিছু আমার জন্য খুব বেশি পরিশ্রুত।

সুতরাং আমি আমার নিজের লিখেছিলাম, এবং যদি আপনার কাছে আধুনিক পাইথন থাকে তবে আপনি সম্ভবত এটি আপনার বাশ শেল থেকে কল করতে পারেন। এটিতে কয়েকটি সাধারণ পাইথন কোডিং কনভেনশন মেনে চলার সুবিধা রয়েছে এবং এমনকি বুদ্ধিমান ত্রুটি বার্তা এবং সহায়তা সরবরাহ করে। এটি ব্যবহার করার জন্য, এটির নামকরণ করুন মাইকনফগ.পিপি (এটিকে কনফিগারপার্পি.পি বলবেন না বা এটি নিজে আমদানির চেষ্টা করতে পারে) এটি কার্যকর করার যোগ্য করুন এবং এটিকে কল করুন

value=$(myconfig.py something.ini sectionname value)

লিনাক্সে পাইথন 3.5 এর জন্য আমার কোডটি এখানে রয়েছে:

#!/usr/bin/env python3
# Last Modified: Thu Aug  3 13:58:50 PDT 2017
"""A program that Bash can call to parse an .ini file"""

import sys
import configparser
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="A program that Bash can call to parse an .ini file")
    parser.add_argument("inifile", help="name of the .ini file")
    parser.add_argument("section", help="name of the section in the .ini file")
    parser.add_argument("itemname", help="name of the desired value")
    args = parser.parse_args()

    config = configparser.ConfigParser()
    config.read(args.inifile)
    print(config.get(args.section, args.itemname))

2

জটিল সরলতা

ini ফাইল

test.ini

[section1]
name1=value1
name2=value2
[section2]
name1=value_1
  name2  =  value_2

পড়ুন এবং সম্পাদন সঙ্গে বাশ স্ক্রিপ্ট

/ বিন / পার্সিনী

#!/bin/bash

set +a
while read p; do
  reSec='^\[(.*)\]$'
  #reNV='[ ]*([^ ]*)+[ ]*=(.*)'     #Remove only spaces around name
  reNV='[ ]*([^ ]*)+[ ]*=[ ]*(.*)'  #Remove spaces around name and spaces before value
  if [[ $p =~ $reSec ]]; then
      section=${BASH_REMATCH[1]}
  elif [[ $p =~ $reNV ]]; then
    sNm=${section}_${BASH_REMATCH[1]}
    sVa=${BASH_REMATCH[2]}
    set -a
    eval "$(echo "$sNm"=\""$sVa"\")"
    set +a
  fi
done < $1

তারপরে অন্য স্ক্রিপ্টে আমি কমান্ডের ফলাফল উত্স করি এবং এর মধ্যে যে কোনও ভেরিয়েবল ব্যবহার করতে পারি

test.sh

#!/bin/bash

source parseini test.ini

echo $section2_name2

অবশেষে কমান্ড লাইন থেকে আউটপুট এইভাবে হয়

# ./test.sh 
value_2

দুর্দান্ত সমাধান! ধন্যবাদ!
মাইকেল

2

এখানে আমার সংস্করণটি রয়েছে, যা বিভাগগুলি পার্স করে এবং এটির সাথে একটি বিশ্বব্যাপী এসোসিয়েটিভ অ্যারে g_iniProperties পপুলেট করে। নোট করুন যে এটি কেবল ব্যাশ v4.2 এবং এর চেয়ে বেশি ক্ষেত্রে কাজ করে।

function parseIniFile() { #accepts the name of the file to parse as argument ($1)
    #declare syntax below (-gA) only works with bash 4.2 and higher
    unset g_iniProperties
    declare -gA g_iniProperties
    currentSection=""
    while read -r line
    do
        if [[ $line = [*  ]] ; then
            if [[ $line = [* ]] ; then 
                currentSection=$(echo $line | sed -e 's/\r//g' | tr -d "[]")  
            fi
        else
            if [[ $line = *=*  ]] ; then
                cleanLine=$(echo $line | sed -e 's/\r//g')
                key=$currentSection.$(echo $cleanLine | awk -F: '{ st = index($0,"=");print  substr($0,0,st-1)}')
                value=$(echo $cleanLine | awk -F: '{ st = index($0,"=");print  substr($0,st+1)}')
                g_iniProperties[$key]=$value
            fi
        fi;
    done < $1
}

এবং এখানে উপরের ফাংশনটি ব্যবহার করে একটি নমুনা কোড দেওয়া হল:

parseIniFile "/path/to/myFile.ini"
for key in "${!g_iniProperties[@]}"; do
    echo "Found key/value $key = ${g_iniProperties[$key]}"
done

1

এই স্ক্রিপ্ট নিম্নলিখিত হিসাবে পরামিতি পাবেন:

মানে আপনার আইএনআই থাকলে:

pars_ini.ksh <ini file> <ini file> <নাম ini file> <নামতে নাম = ফেরত আসার মান>

যেমন এটি কল কিভাবে:


[পরিবেশ]

a = x

[ডাটাবেস_সেক্টর]

ডিএসএন = কিছু


তারপরে ফোন করা:

pars_ini.ksh /users/bubu_user/paraters.ini ডাটাবেস_সেক্টর ডিএসএন

এটি নিম্নলিখিত "কিছু" পুনরুদ্ধার করবে

স্ক্রিপ্ট "pars_ini.ksh":

\#!/bin/ksh

\#INI_FILE=path/to/file.ini

\#INI_SECTION=TheSection

\# BEGIN parse-ini-file.sh

\# SET UP THE MINIMUM VARS FIRST

alias sed=/usr/local/bin/sed

INI_FILE=$1

INI_SECTION=$2

INI_NAME=$3

INI_VALUE=""


eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \

    -e 's/;.*$//' \

    -e 's/[[:space:]]*$//' \

    -e 's/^[[:space:]]*//' \

    -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \

   < $INI_FILE  \

    | sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^;].*\=.*/p;}"`


TEMP_VALUE=`echo "$"$INI_NAME`

echo `eval echo $TEMP_VALUE`

1

আমি আমার বাশ স্ক্রিপ্টে অন্তর্ভুক্ত করার জন্য একটি দ্রুত এবং সহজ অজগর স্ক্রিপ্ট লিখেছিলাম।

উদাহরণস্বরূপ, আপনার আইএনআই ফাইলটি কল করা হয় food.ini এবং ফাইলে আপনার কয়েকটি বিভাগ এবং কয়েকটি লাইন থাকতে পারে:

[FRUIT]
Oranges = 14
Apples = 6

এই ছোট 6 লাইন পাইথন স্ক্রিপ্টটি অনুলিপি করুন এবং এটি সংরক্ষণ করুন configparser.py

#!/usr/bin/python
import configparser
import sys
config = configparser.ConfigParser()
config.read(sys.argv[1])
print config.get(sys.argv[2],sys.argv[3])

এখন, আপনার বাশ স্ক্রিপ্টে আপনি উদাহরণস্বরূপ এটি করতে পারেন।

OrangeQty=$(python configparser.py food.ini FRUIT Oranges)

বা

ApplesQty=$(python configparser.py food.ini FRUIT Apples)
echo $ApplesQty

এই অনুমানগুলি:

  1. আপনি পাইথন ইনস্টল করেছেন
  2. আপনার কনফিগার পার্সার লাইব্রেরি ইনস্টল করা আছে (এটি একটি স্টাডি পাইথন ইনস্টলেশন সাথে আসা উচিত)

আশা করি এটি সহায়তা করে : ¬)


আমি এমন কিছু সন্ধান করছিলাম যা কেবল এটি করেছিল তাই আমি উদাহরণটি অনুসরণ করেছি এবং এটি ঠিক কাজ করে। আমি ভুলে গেছি আমি এই লিখেছি !!!! আমি নিজের পক্ষে ভোট দেওয়ার চেষ্টা করেছি কিন্তু হায় আমি নিজের পক্ষে ভোট দিতে পারি না !!! হা হা
জো_জীবন

0

ওয়ান-লাইনারের আমার সংস্করণ

#!/bin/bash
#Reader for MS Windows 3.1 Ini-files
#Usage: inireader.sh

# e.g.: inireader.sh win.ini ERRORS DISABLE
# would return value "no" from the section of win.ini
#[ERRORS]
#DISABLE=no
INIFILE=$1
SECTION=$2
ITEM=$3
cat $INIFILE | sed -n /^\[$SECTION\]/,/^\[.*\]/p | grep "^[:space:]*$ITEM[:space:]*=" | sed s/.*=[:space:]*//

0

সবেমাত্র নিজের পার্সার লেখা শেষ করেছেন। আমি এখানে পাওয়া বিভিন্ন পার্সার ব্যবহার করার চেষ্টা করেছি, কেউ কেউ ksh93 (এআইএক্স) এবং ব্যাশ (লিনাক্স) উভয়ের সাথে কাজ করছে বলে মনে হচ্ছে না।

এটি পুরানো প্রোগ্রামিং শৈলী - লাইন দ্বারা লাইন পার্সিং। খুব দ্রুত যেহেতু এটি কয়েকটি বাহ্যিক আদেশ ব্যবহার করেছে। অ্যারের গতিশীল নামের জন্য সমস্ত বিকাশ প্রয়োজনীয়তার কারণে কিছুটা ধীর।

আইএনআই 3 টি বিশেষ সিনট্যাক্স সমর্থন করে:

  • સમાવેશfile = ini ফাইল -> একটি অতিরিক্ত ইনআই ফাইল লোড করুন। একাধিক ফাইলে আইএনআই বিভক্ত করার জন্য দরকারী বা কনফিগারেশনের কিছু অংশ পুনরায় ব্যবহার করুন
  • સમાવેશir = ডিরেক্টরি -> অন্তর্ভুক্ত ফাইল হিসাবে একই, তবে একটি সম্পূর্ণ ডিরেক্টরি অন্তর্ভুক্ত
  • অন্তর্ভুক্তি = বিভাগ -> বর্তমান বিভাগে একটি বিদ্যমান বিভাগ অনুলিপি করুন।

আমি সমস্ত জটিল সিনট্যাক্স ব্যবহার করে বেশ জটিল, পুনরায় ব্যবহারযোগ্য ইনআই ফাইল রাখতে পারি। নতুন ওএস ইনস্টল করার সময় পণ্যগুলি ইনস্টল করতে দরকারী - আমরা এটি অনেক কিছু করি।

Values ​​{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"
    }

0

এই বাস্তবায়ন awkনিম্নলিখিত সুবিধা ব্যবহার করে এবং রয়েছে:

  1. কেবল প্রথম মিলের এন্ট্রিটি ফেরত দেবে
  2. A দিয়ে শুরু হওয়া লাইন উপেক্ষা করে ;
  3. শীর্ষস্থানীয় এবং পূর্ববর্তী সাদা স্থান ছাঁটাই, তবে অভ্যন্তরীণ সাদা স্থান নয়

ফর্ম্যাট সংস্করণ :

awk -F '=' '/^\s*database_version\s*=/ {
            sub(/^ +/, "", $2);
            sub(/ +$/, "", $2);
            print $2;
            exit;
          }' parameters.ini

ওয়ান-লাইনার :

awk -F '=' '/^\s*database_version\s*=/ { sub(/^ +/, "", $2); sub(/ +$/, "", $2); print $2; exit; }' parameters.ini

0

আমি যখন বেস 64 এ কোনও পাসওয়ার্ড ব্যবহার করি, আমি বিভাজককে ":" রেখেছি কারণ বেস 64 স্ট্রিংটিতে "=" থাকতে পারে। উদাহরণস্বরূপ (আমি ব্যবহার করি ksh):

> echo "Abc123" | base64
QWJjMTIzCg==

ইন parameters.iniলাইন করা pass:QWJjMTIzCg==, এবং পরিশেষে:

> PASS=`awk -F":" '/pass/ {print $2 }' parameters.ini | base64 --decode`
> echo "$PASS"
Abc123

যদি রেখার ফাঁকির মতো জায়গা থাকে "pass : QWJjMTIzCg== "তবে | tr -d ' 'এগুলি ছাঁটাতে:

> PASS=`awk -F":" '/pass/ {print $2 }' parameters.ini | tr -d ' ' | base64 --decode`
> echo "[$PASS]"
[Abc123]

0

এটি সিস্টেম পার্ল ব্যবহার করে এবং নিয়মিত এক্সপ্রেশনগুলি পরিষ্কার করে:

cat parameters.ini | perl -0777ne 'print "$1" if /\[\s*parameters\.ini\s*\][\s\S]*?\sdatabase_version\s*=\s*(.*)/'

0

অন্য কারওর মধ্যে "কারেন গ্যাব্রিলিয়ান" এর উত্তরটি সবচেয়ে ভাল ছিল তবে কিছু পরিবেশে আমরা জাগ্রত করি না, সাধারণ ব্যস্তবক্সের মতো আমি উত্তরটি নীচের কোড দিয়ে পরিবর্তন করেছিলাম।

trim()
{
    local trimmed="$1"

    # Strip leading space.
    trimmed="${trimmed## }"
    # Strip trailing space.
    trimmed="${trimmed%% }"

    echo "$trimmed"
}


  function parseIniFile() { #accepts the name of the file to parse as argument ($1)
        #declare syntax below (-gA) only works with bash 4.2 and higher
        unset g_iniProperties
        declare -gA g_iniProperties
        currentSection=""
        while read -r line
        do
            if [[ $line = [*  ]] ; then
                if [[ $line = [* ]] ; then 
                    currentSection=$(echo $line | sed -e 's/\r//g' | tr -d "[]")  
                fi
            else
                if [[ $line = *=*  ]] ; then
                    cleanLine=$(echo $line | sed -e 's/\r//g')
                    key=$(trim $currentSection.$(echo $cleanLine | cut -d'=' -f1'))
                    value=$(trim $(echo $cleanLine | cut -d'=' -f2))
                    g_iniProperties[$key]=$value
                fi
            fi;
        done < $1
    }

আমি পুরোপুরি নিশ্চিত নই যে এটি কতটা সম্ভাব্য যে অজস্রটি অনুপস্থিত, তবে সিড, কাট এবং সিনট্যাক্সের মতো তুলনামূলকভাবে আরও উন্নত বাশ পাওয়া যায়।
ওন্দ্রেজ কে।

বেশিরভাগ প্রাথমিক রুট ফাইল সিস্টেমগুলি শেল স্ক্রিপ্ট হিসাবে / linuxrc বা / init প্রয়োগ করে এবং এর ফলে কিছু প্রয়োজনীয় ব্যবহারকারী-স্থানের ইউটিলিটি সহ একটি সর্বনিম্ন শেল (সাধারণত / বিন / অ্যাশ) অন্তর্ভুক্ত থাকে
এহসান আহমাদি

অবশ্যই আমি কিছুটা অবাক হলাম আপনি কোনও ব্যস্ততা ছাড়াই আপনার ব্যস্তবক্সটি তৈরি করতেন তবে তবুও বিভিন্ন "বাশিজম" এর জন্য সেড, কাট এবং সমর্থন সহ। এটি সম্ভব হবে না এমন নয়, কেবল আমাকে অবাক করে তোলে। ;)
ওন্দ্রেজ কে।

অন্যান্য সরঞ্জামগুলি অ্যাজকের চেয়ে বেশি আলোকসজ্জা। আপনি যদি উবুন্টু ডিস্ট্রোতে ইনি্রামফ-সরঞ্জামগুলির সাহায্যে স্ক্রিপ্টটি লিখেন, আপনি দেখতে পাবেন যে আপনার কাছে বিশুদ্ধতা নেই এবং সেড, গ্রেপ ... এর মতো অন্যান্য সরঞ্জামগুলিও ন্যূনতম ক্রিয়াকলাপে রয়েছে।
এহসান আহমদী

অবশ্যই, আমি জিএনইউ অ্যাডক বা অন্য পুরো ব্লক অ্যাজকের কথা বলছি না, কেবল বিস্মৃত সমর্থনটি অন্তর্ভুক্ত না করার জন্য ব্যস্তবক্স কনফিগার করে একজনের কতটুকু সঞ্চয় করে তা ভাবছেন (যেমন, উল্লিখিত অন্যান্য বিটগুলি সেই কনফিগারেশনের বাইরে না ছাঁটা হয়েছে)। এটি হতে পারে যে * বন্টু আরআরডি এর মতো একটি রয়েছে। কম্বো / পছন্দটি সম্পর্কে কেবল ভাবছি।
ওন্দ্রেজ কে।

0

পাইথন যদি উপলভ্য থাকে তবে নিম্নলিখিত বিভাগগুলি, কী এবং মানগুলি পড়তে হবে এবং "[বিভাগ] _ [কী]" ফর্ম্যাট অনুসরণ করে তাদের নামগুলির সাথে ভেরিয়েবলগুলিতে সেভ করবে। পাইথন .ini ফাইলগুলি সঠিকভাবে পড়তে পারে, তাই আমরা এটি ব্যবহার করি।

#!/bin/bash

eval $(python3 << EOP
from configparser import SafeConfigParser

config = SafeConfigParser()
config.read("config.ini"))

for section in config.sections():
    for (key, val) in config.items(section):
        print(section + "_" + key + "=\"" + val + "\"")
EOP
)

echo "Environment_type:  ${Environment_type}"
echo "Environment_name:  ${Environment_name}"

config.ini

[Environment]
  type                = DEV
  name                = D01

0

আপনি INI ডেটা পার্সিং হিসাবে একটি CSV পার্সার xsv ব্যবহার করতে পারেন ।

cargo install xsv
$ cat /etc/*release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
$ xsv select -d "=" - <<< "$( cat /etc/*release )" | xsv search --no-headers --select 1 "DISTRIB_CODENAME" | xsv select 2
xenial

বা একটি ফাইল থেকে।

$ xsv select -d "=" - file.ini | xsv search --no-headers --select 1 "DISTRIB_CODENAME" | xsv select 2

0

বিভাগগুলি ব্যবহার করে, এটি কাজটি করবে:

কাঁচা আউটপুট উদাহরণ:

$ ./settings
[section]
SETTING_ONE=this is setting one
SETTING_TWO=This is the second setting
ANOTHER_SETTING=This is another setting

রেজিপ্স্প পার্সিং:

$ ./settings | sed -n -E "/^\[.*\]/{s/\[(.*)\]/\1/;h;n;};/^[a-zA-Z]/{s/#.*//;G;s/([^ ]*) *= *(.*)\n(.*)/\3_\1='\2'/;p;}"
section_SETTING_ONE='this is setting one'
section_SETTING_TWO='This is the second setting'
section_ANOTHER_SETTING='This is another setting'

এখন সব একসাথে:

$ eval "$(./settings | sed -n -E "/^\[.*\]/{s/\[(.*)\]/\1/;h;n;};/^[a-zA-Z]/{s/#.*//;G;s/([^ ]*) *= *(.*)\n(.*)/\3_\1='\2'/;p;}")"
$ echo $section_SETTING_TWO
This is the second setting

0

আমার কাছে দুর্দান্ত ওয়ান-লাইনার রয়েছে (আপনি নিশ্চিত করে ইনস্টল করেছেন phpএবং jqস্থাপন করেছেন):

cat file.ini | php -r "echo json_encode(parse_ini_string(file_get_contents('php://stdin'), true, INI_SCANNER_RAW));" | jq '.section.key'

0

ওয়ান-লাইন সেডের উত্তরের ব্যাখ্যা।

[section1]
param1=123
param2=345
param3=678

[section2]
param1=abc
param2=def
param3=ghi

[section3]
param1=000
param2=111
param3=222
sed -nr "/^\[section2\]/ { :l /^\s*[^#].*/ p; n; /^\[/ q; b l; }" ./file.ini

বোঝার জন্য, লাইনটি এভাবে ফর্ম্যাট করা সহজ হবে:

sed -nr "
      # start processing when we found the word \"section2\"
      /^\[section2\]/  { #the set of commands inside { } will be executed
          #create a label \"l\"  (https://www.grymoire.com/Unix/Sed.html#uh-58)
          :l /^\s*[^#].*/ p; 
          # move on to the next line. For the first run it the \"param1=abc\"
          n; 
          # check if this line is beginning of new section. If yes - then exit.
          /^\[/ q
          #otherwise jump to the label \"l\"
          b l
          }

" file.ini
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.