137 votes

Comment saisir une valeur INI dans un script shell script ?

J'ai un fichier parameters.ini, tel que :

[parameters.ini]
    database_user    = user
    database_version = 20110611142248

Je veux lire et utiliser la version de la base de données spécifiée dans le fichier parameters.ini à partir d'un shell bash script pour pouvoir la traiter.

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

Comment dois-je m'y prendre ?

6 votes

Est-ce que l'une de ces réponses respecte les sections ?

0 votes

Notez que tout script qui commence par #!/bin/sh est un script POSIX sh, et non un script bash. C'est une distinction importante, car sh ne dispose pas de fonctionnalités comme les tableaux et les cartes (que bash appelle "tableaux associatifs") qui sont très utiles pour construire ce genre de choses.

1voto

k23j4 Points 493

Vous pouvez utiliser un analyseur CSV xsv comme l'analyse des données 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

ou à partir d'un fichier.

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

1voto

Yann Bizeul Points 11

Si vous utilisez des sections, cela fera l'affaire :

Exemple de sortie brute :

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

Analyse syntaxique 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'

Maintenant tous ensemble :

$ 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

0voto

Chris Points 37

Ceci est basé sur la réponse de Juarez Rudsatz, donc merci beaucoup de m'avoir mis dans la bonne direction.

J'ai eu un petit problème avec lui dans Ubuntu 20.04 bash.

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,/#/) { 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==substr($1, 0, length(key))) { print substr($0, length(key)+2) }
        if (params==1) { printf "%s\n",$1,$3 }
    }
    }'
}

Les différences ici sont le substrat dans le dernier bloc, l'exemple de Juarez ajoutait un = supplémentaire lors de l'affichage des paramètres d'une section. Il n'affichait rien non plus lors de l'affichage des options individuelles.

Pour remédier au = supplémentaire, j'ai supprimé =%s de la ligne params==1. Pour remédier aux valeurs manquantes, j'ai retravaillé la ligne params==2 presque entièrement. J'ai ajouté une correspondance pour exclure ; les lignes commentées également.

Cet exemple fonctionnera avec des fichiers INI tels que

[default]
opt=1
option=option
option1=This is just another example
example=this wasn't working before
#commented=I will not be shown
;commentedtoo=Neither Will I.

[two]
opt='default' 'opt'just doesnt get me! but 'two' 'opt' does :)
iam=not just for show

Pour utiliser ce script, ce n'est pas différent de l'exemple de Juarez.

cat options.ini | parse_ini                     # Show Sections
cat options.ini | parse_ini 'default'           # Show Options with values
cat options.ini | parse_ini 'default' 'option'  # Show Option Value
cat options.ini | parse_ini 'two' 'iam'         # Same as last but from another section

Cela fonctionne bien sûr comme prévu. Alors quoi d'autre, ah oui, vous pourriez vouloir un fichier de fonctions pour désencombrer votre script, et vous voulez probablement accéder aux valeurs. Voici un exemple rapide.

app="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" # get the path to your program
source $app/functions.script # could be in a subdirectory.
somevar=$(cat $app/options.ini | parse_ini 'section' 'option') # Now its in a variable.

0voto

Tyler Hansen Points 1

J'ai pris la fonction que Chris a écrite et l'ai transformée en un shell script pour un usage personnel. N'hésitez pas à l'utiliser vous-même. Merci Chris !

https://github.com/tyler-hansen/general_use

J'ai fourni un binaire exécutable et un code source et comment les utiliser.

read-ini [arg1] [arg2] [arg3]
Arguments:
         arg1 = config.ini file
         arg2 = section (defined in ini file with [])
         arg3 = variable key (within the section)

Ejemplo:

 $ read-ini config.ini FANTOM path  
 /data/hodges_lab/ATAC-STARR_B-cells/data/hansen-fong/fantom

0voto

Valentin Heinitz Points 1231

Ma version du one-liner

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X