programing

셸 스크립트 내에서 INI 값을 취득하려면 어떻게 해야 합니까?

easyjava 2023. 4. 19. 23:36
반응형

셸 스크립트 내에서 INI 값을 취득하려면 어떻게 해야 합니까?

다음과 같은 parameters.ini 파일이 있습니다.

[parameters.ini]
    database_user    = user
    database_version = 20110611142248

bash 셸 스크립트 내에서 parameters.ini 파일에 지정된 데이터베이스 버전을 읽어 사용하고 싶습니다.

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

이거 어떻게 해요?

그 라인에 그리핑한 후 awk를 사용하면 어떨까요?

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

bash 네이티브 파서를 사용하여 다음과 같이 ini 값을 해석할 수 있습니다.

$ source <(grep = file.ini)

샘플 파일:

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

, 「변수」를 만 하면 .echo $var1위와 같이 어레이를 사용할 수도 있습니다(echo ${IPS[@]}를 참조해 주세요.

1개의 값만 사용하는 경우 grep만 사용합니다.

source <(grep var1 file.ini)

데모의 경우 아시네마에서 이 녹음을 확인합니다.

데이터를 해석하기 위해 외부 라이브러리가 필요하지 않으므로 간단하지만 몇 가지 단점이 있습니다.예를 들어 다음과 같습니다.

  • 에 공백이 = (과 값) (으)ㄹ 수 있다, 하다, 하다, 하다, 이렇게요.

      $ 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또는 ).

    예.

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

    :서 ★★★★★★★★★★★★★★★★★★★★」-A5는 섹션에서 읽을 행의 수입니다.sourcecat디버깅할 수 있습니다.

  • 오류가 있는 명령을 추가하여하십시오.2>/dev/null

다음 항목도 참조하십시오.

세드 원라이너, 구간이 고려되는군요.파일 예:

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

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

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

섹션2의 param2를 원한다고 칩니다.다음을 실행합니다.

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

너에게 줄 것이다

def

Bash는 이러한 파일에 대한 파서를 제공하지 않습니다.물론 awk 명령어 또는 sed 콜을 몇 개 사용할 수 있지만 bash-priest이며 다른 셸을 사용하지 않을 경우 다음 불분명한 코드를 사용해 볼 수 있습니다.

#!/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"

Bash ini-parser는 The Old School DevOps 블로그 사이트에 있습니다.

bash 본문에 .ini 파일을 포함하기만 하면 됩니다.

파일 예시ini:

DBNAME=test
DBUSER=scott
DBPASSWORD=tiger

파일 예시

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

도구를 사용하여 다음과 같은 ini 값을 가져올 수 있습니다.

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

지금까지 본 솔루션도 모두 코멘트를 달았습니다. 코드가 「 」인 이 코멘트 코드는 .;:

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

보다 가능성 있는 해결책의 하나

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

ini 스타일의 my_filemy_key 값을 표시합니다.

sed -n -e 's/^\s*my_key\s*=\s*//p' my_file
  • -n 하지 않습니다------------------------------------------------------------------------------------------------
  • -e 실행해 주세요.
  • s/PATTERN//p이 임의의 합니다.-- : 、 -- 、 -- 、 -- 、 -- -- -- -- -- -- -- 。
  • ^에서 시작합니다--행의 선두에서 합니다.
  • \s 문자---------------------------------------
  • *0 ( 문자)-- 0 이 되다 (공백 문자)

예:

$ 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

그래서:

행이 0 또는 다수의 공백 문자로 시작하고, 그 뒤에 my_key 문자열, 0 또는 다수의 공백 문자, 등호, 0 또는 다수의 공백 문자가 이어지는 패턴을 찾습니다.해당 패턴에 따라 나머지 내용을 해당 줄에 표시합니다.

답변과 로 Python을 .-cPython은 다음과 같습니다.

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

이것은 Python 표준 라이브러리만 필요로 하는 장점이 있고 별도의 스크립트 파일을 쓰지 않는다는 장점이 있습니다.

또는 읽기 쉽도록 여기를 참조해 주세요.따라서 다음과 같습니다.

#!/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

sed의

하시면 됩니다.sed특히 다음과 같은 섹션 이름이 있는 경우 ini 구성 파일을 구문 분석합니다.

# 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'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE:

# 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
}

그러면 ini 데이터가 다음과 같은 플랫 형식으로 변환됩니다.

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★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

크레딧과 소스: 셸 스크립트 설정 파일, Michael Grünewald


또는 다음 프로젝트를 사용할 수 있습니다. , 를 사용하여 구성 파서를 사용할 수 있습니다.sed.

셸 스크립트(bash가 아닌 셸 읽기)에서 INI 파일을 읽고 싶은 사람(나처럼)을 위해 작은 도우미 라이브러리를 준비했습니다.

https://github.com/wallyhall/shini (MIT 라이선스, 원하는 대로 사용하세요)코드가 길어서 인라인으로 링크했습니다.)

한 '하다'보다'복잡하다'고 할 수 있습니다sed위에 제시된 행은 매우 유사한 기준으로 작동합니다.

에서 한 읽는 - 를 찾습니다(예: 검색 - 검색).[section]값 선언syslog/syslog)key=value를 참조해 주세요.

최종적으로는 자신의 기능(섹션, 키 및 가치)에 대한 콜백을 얻을 수 있습니다.

이 버전은 섹션을 해석하고 글로벌 관련 배열 g_iniProperties를 포함하는 버전입니다.이 기능은 bash 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

른른른른른른을 사용한 awk아, 아, 아, 아, 아, 아, 아, 아, 아, 아.

function parse_ini() {
  cat /dev/stdin | awk -v section="$1" -v key="$2" '
    BEGIN {
      if (length(key) > 0) { params=2 }
      else if (length(section) > 0) { params=1 }
      else { params=0 }
    }
    match($0,/#/) { next }
    match($0,/^\[(.+)\]$/){
      current=substr($0, RSTART+1, RLENGTH-2)
      found=current==section
      if (params==0) { print current }
    }
    match($0,/(.+)=(.+)/) {
       if (found) {
         if (params==2 && key==$1) { print $3 }
         if (params==1) { printf "%s=%s\n",$1,$3 }
       }
    }'
}

0 ~ 2 파라미터 사이의 콜 통과를 사용할 수 있습니다.

cat myfile1.ini myfile2.ini | parse_ini # List section names

cat myfile1.ini myfile2.ini | parse_ini 'my-section' # Prints keys and values from a section

cat myfile1.ini myfile2.ini | parse_ini 'my-section' 'my-key' # Print a single value

복잡한 단순성

ini 파일

test.ini

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

bash 스크립트 읽기 및 실행

/bin/binini

#!/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

일부 답변은 댓글을 존중하지 않습니다.일부는 섹션을 존중하지 않는다.일부는 하나의 구문만 인식합니다(":" 또는 "="만 인식합니다.일부 Python 응답은 캡티얼라이제이션이 다르거나 시스템모듈 Import에 실패하여 기계에서 실패합니다.다 저한테는 너무 간결해요.

그래서 제가 직접 썼죠. 만약 당신이 현대의 파이썬을 가지고 있다면, 아마도 당신은 이것을 Bash 쉘에서 불러낼 수 있을 겁니다.일반적인 Python 코딩 규약을 준수할 수 있는 장점이 있으며, 합리적인 오류 메시지와 도움말도 제공합니다.사용하기 위해서는 myconfig.py과 같은 이름을 붙입니다(configparser.py이라고 부르지 마십시오.그렇지 않으면 Import를 시도하여 실행 가능 상태로 만들고 다음과 같이 부릅니다).

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

Linux에서의 Python 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))

bash 스크립트에 포함시키기 위해 빠르고 쉬운 python 스크립트를 작성했습니다.

들어 은 "ini" 입니다.food.ini파일에는 다음과 같은 섹션과 행을 포함할 수 있습니다.

[FRUIT]
Oranges = 14
Apples = 6

하여 Python으로 합니다.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])

예를 들어 bash 스크립트에서는 이렇게 할 수 있습니다.

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

또는

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

이 전제조건은 다음과 같습니다.

  1. Python이 설치되어 있습니다.
  2. configparser 라이브러리가 설치되어 있어야 합니다(이것은 std python 설치와 함께 제공됩니다).

도움이 되었으면 좋겠다:))

원라이너 SED에 대한 답변에 대한 설명입니다.

[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 is 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

이 스크립트는 다음과 같은 파라미터를 가져옵니다.

즉, ini에 다음이 있는 경우:

pars_ini.ksh < ini 파일 경로> < Ini 파일 내의 섹터 이름> < 반환할 이름=값>

예: 호출 방법:


[환경]

a=x

[데이터베이스_섹터]

DSN = something


그 후 호출:

pars_ini.ksh/users/bubu_user/parameters.ini DataBase_Sector DSN

다음과 같은 "something"을 검색합니다.

스크립트 "snot_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`

에서는, 「」를 사용합니다.awk는음

  1. 일치하는 첫 번째 항목만 반환합니다.
  2. 의 행으로 합니다.;
  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

CSV 파서 xsv를 INI 데이터의 해석으로서 사용할 수 있습니다.

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

내 버전의 원라이너

#!/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:]*//

내 파서 쓰는 거 막 끝냈어여기에 있는 다양한 파서를 사용하려고 했는데, ksh93(AIX)과 bash(Linux) 모두 동작하지 않는 것 같습니다.

한 줄씩 구문 분석하는 오래된 프로그래밍 스타일입니다.외부 명령어를 거의 사용하지 않았기 때문에 매우 빠릅니다.어레이의 동적 이름에 필요한 모든 평가로 인해 약간 느립니다.

ini는 다음 3가지 특별한 구문을 지원합니다.

  • includefile=ini file --> 추가 ini 파일을 로드합니다.ini를 여러 파일로 분할하거나 일부 구성을 재사용할 때 유용합니다.
  • includedir=directory --> includefile과 동일하지만 완전한 디렉토리를 포함합니다.
  • includesection=section --> 기존 섹션을 현재 섹션에 복사합니다.

매우 복잡하고 재사용 가능한 ini 파일을 만들기 위해 모든 구문을 사용했습니다.새로운 OS를 인스톨 할 때, 제품을 인스톨 할 때에 편리합니다.다양한 작업을 하고 있습니다.

${ini[$section]를 사용하여 값에 액세스할 수 있습니다.$item]}.이 명령을 호출하기 전에 어레이를 정의해야 합니다.

즐겁게 보내세요.다른 사람에게 유용했으면 좋겠네요!

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"
    }

, 문자열에 「」가 붙을 수 있기 「:」가.base64 에는 「=」가 붙습니다.예를 들어 (사용하고 있습니다)ksh

> echo "Abc123" | base64
QWJjMTIzCg==

»parameters.inipass: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]

여기에는 system perl 및 clean 정규 표현이 사용됩니다.

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

다른 답변 중 "Karen Gabrielyan"의 답변이 가장 좋았지만, 일반적인 busybox와 같이 우리가 가지고 있지 않은 환경에서는 아래의 코드로 답변을 변경했습니다.

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
    }

Python을 사용할 수 있는 경우, 다음은 모든 섹션, 키 및 값을 읽고 "섹션" 형식 뒤에 있는 이름으로 변수에 저장합니다._[키].Python은 .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

섹션을 사용하는 경우 다음과 같은 작업을 수행합니다.

raw 출력 예:

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

Regexp 구문 분석:

$ ./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

는 멋진 가지고 .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'

수 있는 에서는, .따라서 이 솔루션에서는 다음과 같은 툴이 필요하지 않습니다.sed ★★★★★★★★★★★★★★★★★」awk:

grep '^\[section\]' -A 999 config.ini | tail -n +2  | grep -B 999 '^\[' | head -n -1 | grep '^key' | cut -d '=' -f 2 

상기의 .999 의 「」를 참조해 주세요.결과 값을 트리밍하여 값 뒤에 공백 또는 주석 문자열을 삭제할 수 있습니다.를제 remove remove remove를 remove remove 를 remove 。^질문의 예시와 같이 행의 선두에서 시작하지 않는 키를 일치시킬 필요가 있는 경우.이러한 경우 공백 및 탭을 명시적으로 일치시키는 것이 좋습니다.

특정 섹션에 여러 개의 값이 있지만 파일을 여러 번 읽지 않도록 하려면 다음 절차를 수행합니다.

CONFIG_SECTION=$(grep '^\[section\]' -A 999 config.ini | tail -n +2  | grep -B 999 '^\[' | head -n -1)

KEY1=$(echo ${CONFIG_SECTION} | tr ' ' '\n' | grep key1 | cut -d '=' -f 2)
echo "KEY1=${KEY1}"
KEY2=$(echo ${CONFIG_SECTION} | tr ' ' '\n' | grep key2 | cut -d '=' -f 2)
echo "KEY2=${KEY2}"

언급URL : https://stackoverflow.com/questions/6318809/how-do-i-grab-an-ini-value-within-a-shell-script

반응형