2015-03-03 2 views
22

Ich versuche zu lesen, eine Eigenschaftsdatei von einem Shell-Skript, das eine Periode enthält Zeichen wie unten (.):Wie eine .properties-Datei, die enthält Schlüssel zu lesen, der eine Periode Zeichen mit Shell-Skript

# app.properties 
db.uat.user=saple user 
db.uat.passwd=secret 


#/bin/sh 
function pause(){ 
    read -p "$*" 
} 

file="./app.properties" 

if [ -f "$file" ] 
then 
    echo "$file found." 
. $file 

echo "User Id " $db.uat.user 
echo "user password =" $db.uat.passwd 
else 
    echo "$file not found." 
fi 

Ich habe versucht, die Datei nach dem Sourcing der Datei zu analysieren, aber es funktioniert nicht, da die Schlüssel das "." Zeichen und es gibt auch Leerzeichen in diesem Wert.

Meine Properties-Datei befindet sich immer im gleichen Verzeichnis des Skripts oder irgendwo in/usr/share/doc

Antwort

20

Da (Bourne) Shell-Variablen keine Punkte enthalten können, können Sie sie durch Unterstriche ersetzen. Lies jede Zeile, übersetze. im Schlüssel zu _ und auszuwerten.

#/bin/sh 

file="./app.properties" 

if [ -f "$file" ] 
then 
    echo "$file found." 

    while IFS='=' read -r key value 
    do 
    key=$(echo $key | tr '.' '_') 
    eval "${key}='${value}'" 
    done < "$file" 

    echo "User Id  = " ${db_uat_user} 
    echo "user password = " ${db_uat_passwd} 
else 
    echo "$file not found." 
fi 
+0

Gibt es Möglichkeit, ich kann den db_uat_user in einer Variablen speichern und übergeben Sie dann die Variable, um den Wert davon abzurufen. Etwas wie zuerst var_key = db_uat_user und dann echo "user id =" $ {"$ var_key"} Jedenfalls intern der Wert var_key ist db_uat_user ist es möglich, so etwas zu erreichen. –

+0

@AdarshHDDev verschiedene Fragen zu stellen wird von SO abgeraten. In Bezug auf Ihre Frage wurde es oft gefragt und beantwortet, zum Beispiel: http://unix.stackexchange.com/questions/68035/foo-and-zsh – fork2execve

6

Da Variablennamen in der bash-Shell keinen Punkt oder Leerzeichen enthalten kann, ist es besser, ein assoziatives Array zu verwenden, in BASH wie folgt aus:

#!/bin/bash 

# declare an associative array 
declare -A arr 

# read file line by line and populate the array. Field separator is "=" 
while IFS='=' read -r k v; do 
    arr["$k"]="$v" 
done < app.properties 

Testing:

Verwenden erklären -p das Ergebnis zu zeigen:

> declare -p arr 

     declare -A arr='([db.uat.passwd]="secret" [db.uat.user]="saple user")' 
0

@ fork2x

Ich habe wie diese .Please Bewertung versucht und mich zu aktualisieren, ob es richtig Ansatz ist oder nicht.

#/bin/sh 
function pause(){ 
    read -p "$*" 
} 

file="./apptest.properties" 


if [ -f "$file" ] 
then 
    echo "$file found." 

dbUser=`sed '/^\#/d' $file | grep 'db.uat.user' | tail -n 1 | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'` 
dbPass=`sed '/^\#/d' $file | grep 'db.uat.passwd' | tail -n 1 | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'` 

echo database user = $dbUser 
echo database pass = $dbPass 

else 
    echo "$file not found." 
fi 
+0

Ich mag @ Nicolais Antwort am besten – bakoyaro

30

Ich benutze einfach grep innerhalb Funktion in Bash-Skript Eigenschaften erhalten von .properties Datei.

Diese Eigenschaftendatei verwende ich an zwei Orten - zum Einrichten der Entwicklungsumgebung und als Anwendungsparameter.

Ich glaube, dass grep kann langsam in großen Schleifen arbeiten, aber es löst meine Bedürfnisse, wenn ich dev Umgebung vorbereiten möchten.

Hoffe, jemand wird dies nützlich finden.

Beispiel:

Datei: setup.sh

#!/bin/bash 

ENV=${1:-dev} 

function prop { 
    grep "${1}" env/${ENV}.properties|cut -d'=' -f2 
} 

docker create \ 
    --name=myapp-storage \ 
    -p $(prop 'app.storage.address'):$(prop 'app.storage.port'):9000 \ 
    -h $(prop 'app.storage.host') \ 
    -e STORAGE_ACCESS_KEY="$(prop 'app.storage.access-key')" \ 
    -e STORAGE_SECRET_KEY="$(prop 'app.storage.secret-key')" \ 
    -e STORAGE_BUCKET="$(prop 'app.storage.bucket')" \ 
    -v "$(prop 'app.data-path')/storage":/app/storage \ 
    myapp-storage:latest 

docker create \ 
    --name=myapp-database \ 
    -p "$(prop 'app.database.address')":"$(prop 'app.database.port')":5432 \ 
    -h "$(prop 'app.database.host')" \ 
    -e POSTGRES_USER="$(prop 'app.database.user')" \ 
    -e POSTGRES_PASSWORD="$(prop 'app.database.pass')" \ 
    -e POSTGRES_DB="$(prop 'app.database.main')" \ 
    -e PGDATA="/app/database" \ 
    -v "$(prop 'app.data-path')/database":/app/database \ 
    postgres:9.5 

Datei: env/dev.properties

app.data-path=/apps/myapp/ 

#========================================================== 
# Server properties 
#========================================================== 
app.server.address=127.0.0.70 
app.server.host=dev.myapp.com 
app.server.port=8080 

#========================================================== 
# Backend properties 
#========================================================== 
app.backend.address=127.0.0.70 
app.backend.host=dev.myapp.com 
app.backend.port=8081 
app.backend.maximum.threads=5 

#========================================================== 
# Database properties 
#========================================================== 
app.database.address=127.0.0.70 
app.database.host=database.myapp.com 
app.database.port=5432 
app.database.user=dev-user-name 
app.database.pass=dev-password 
app.database.main=dev-database 

#========================================================== 
# Storage properties 
#========================================================== 
app.storage.address=127.0.0.70 
app.storage.host=storage.myapp.com 
app.storage.port=4569 
app.storage.endpoint=http://storage.myapp.com:4569 
app.storage.access-key=dev-access-key 
app.storage.secret-key=dev-secret-key 
app.storage.region=us-east-1 
app.storage.bucket=dev-bucket 

Verbrauch:

./setup.sh dev 
+4

Ich mag diesen Weg. Eine Verbesserung für Ihr grep: Jetzt stimmt es mit der Zeichenfolge irgendwo in der Zeile überein. Sie könnten 'grep '^ \\\ s * $ {1} =" env/$ {ENV} .properties | cut -d' = '-f2' verwenden, um ganze Schlüssel am Anfang der Zeile zu finden (ausgenommen optionale Leerzeichen)). – jhyot

+0

@jhyot, Danke, Sie haben Recht. Zusätzlich hat diese Methode Limits, zB erlaubt sie nicht, auf andere Eigenschaften zu verweisen @ app.v1 = test - $ {app.v2} @. Es löst mein Bedürfnis für jetzt, aber ich glaube, ich muss es sehr bald verbessern. – Nicolai

+0

Sehr nette Annäherung! Ich denke, ich werde es in meiner eigenen Arbeit übernehmen. – bakoyaro

1

Ich fand mit while IFS='=' read -r, um ein bisschen langsam zu sein (Ich weiß nicht warum, vielleicht könnte jemand kurz in einem Kommentar erklären oder auf eine SO-Antwort zeigen?). Ich fand auch @Nicolai sehr sauber als One-Liner, aber sehr ineffizient, da es die gesamte Eigenschaftendatei für jeden einzelnen Anruf von prop immer wieder scannen wird.

Ich fand eine Lösung, die die Frage beantwortet, funktioniert gut und es ist ein One-Liner (Bit verbose Linie obwohl).

Die Lösung macht Sourcing aber massiert die Inhalte vor Sourcing:

#!/usr/bin/env bash 

source <(grep -v '^ *#' ./app.properties | grep '[^ ] *=' | awk '{split($0,a,"="); print gensub(/\./, "_", "g", a[1]) "=" a[2]}') 

echo $db_uat_user 

Erläuterung:

grep -v '^ *#': verwerfen Kommentarzeilen grep '[^ ] *=': verwirft Linien ohne = split($0,a,"="): Splits Linie bei = und speichert in Array a, dh a [1] ist der Schlüssel, a [2] ist der Wert gensub(/\./, "_", "g", a[1]): ersetzt . durch _ print gensub... "=" a[2]} verkettet das Ergebnis von gensub oben mit = und Wert.

+0

Ihr Code gibt mir den Fehler '/ dev/fd/63: Zeile 1: Benutzer: Befehl nicht gefunden' mit'./app.properties' mit den angegebenen Inhalten. – TomRoche

+0

Ich vermute, das liegt daran, dass Sie nicht den Platz im ersten "Wert" der Datei = "Beispielbenutzer" behandeln. – TomRoche

Verwandte Themen