2016-05-01 30 views
0

Ich brauche ein Bash-Skript, das Folgendes tun sollte: - Lesen von einer Eingabedatei Zeile für Zeile, die Format: [Umgebung] = [Dateiname] = [Eigenschaftenschlüssel] = [Eigenschaftswert] - Es wird alle Dateien ändern, indem alle Eigenschaften in einem $ SOURCE-Verzeichnis entsprechend der Eingabedatei ersetzt werden. Jetzt bin ich an dem Punkt "Replace and Count" fest.ersetzen und zählen bash unable durch awk und sed

Der Code, bis die „ersetzen und zählen“ Phase: &, /, ....:

PROPERTIES_LIST=/home/user/test_scripts/envPropList.txt 

SOURCE=/home/user/test_scripts/source-directory 

PROPERTIES_LOCATION=/WEB-INF/classes/ 

PROPERTIES_SOURCE=$SOURCE$PROPERTIES_LOCATION 

ENV=$1 
echo "> Update for ENVIRONMENT: $ENV... Please wait!" 

NR=1 
while read line; do 
    IFS== read env prop <<< "$line" 
    if [[ $env == $ENV]] 
    then 
     IFS== read file key value <<< "$prop" 
     if [[ -z $file ]] || [[ -z $key ]] || [[ -z $value ]] 
     then 
      echo "> [ERROR] [LINE $NR] - WRONG/MISSING PROPERTY: $line" 
     else 
      //MODIFY $file BY REPLACE AND COUNT 
      //IF $key IS NOT FOUND AT ALL AN ERROR MESSAGE SHOULD BE DISPLAYED. ITERATION SHOULD CONTINUE 
      //IF $key IS FOUND MORE THEN ONCE, A WARNING MESSAGE SHOULD BE DISPLAYED. ITERATION SHOULD CONTINUE 

      echo "done" 
     fi 
    fi 
    NR=$(($NR + 1)) 
done <$PROPERTIES_LIST 

ich folgende ohne Erfolg ohne Erfolg, weil Wert in den Eigenschaften jedes Zeichen (wie sein kann, versucht habe,):

COUNT=$(grep -c "$key" $PROPERTIES_SOURCE$file) 
sed -i "s/${OLD}/${NEW}/g" $PROPERTIES_SOURCE$file 

auch als awk nicht funktionierte erwartet:

DEST=/home/user/test_scripts/test.txt 
OLD='asd.asd' 
NEW='test/test?test.test&test=test' 
COUNT=$(grep -c "$OLD" $DEST) 
#sed -i "s/#${OLD}#/#${NEW}#p/g" $DEST 
#echo "$OLD=$NEW" 
echo "nr de rezultate: "$COUNT 
awk -v OLD=$OLD -v NEW=$NEW ' 
    ($0 ~ OLD) {gsub(OLD, NEW); count++}1 
    END{print count " substitutions occured."} 
' "$DEST" 

Und für Eingabedatei:

asd.asd 
ewrqfg 
qweasd.asdqwreqe 
asd asd.asd 
egd 
test 

Ich habe die folgende Ausgabe:

test/test?test.testasd.asdtest=test 
ewrqfg 
qwetest/test?test.testasd.asdtest=testqwreqe 
test/test?test.testasd asdtest=test.asd 
egd 
test 

Wenn ich "&" von $ NEW entfernen, alles geht gut.

Antwort

0

Sie haben nicht Ihre erwartete Ausgabe veröffentlichen, damit es eine Vermutung ist, aber das ist wahrscheinlich das, was Sie wollen:

$ cat tst.sh 
dest='file' 
old='asd.asd' 
new='test/test?test.test&test=test' 
count=$(grep -c "$old" "$dest") 
#sed -i "s/#${old}#/#${new}#p/g" "$dest" 
#echo "$old=$new" 
echo "nr de rezultate: $count" 
awk -v old="$old" -v new="$new" ' 
    { 
     head = "" 
     tail = $0 
     lgth = length(old) 
     while (start = index(tail,old)) { 
      head = head substr(tail,1,start-1) new 
      tail = substr(tail,start+lgth) 
      count++ 
     } 
     print head tail 
    } 
    END { print count+0, "substitutions occured." } 
' "$dest" 

$ ./tst.sh file 
nr de rezultate: 3 
test/test?test.test&test=test 
ewrqfg 
qwetest/test?test.test&test=testqwreqe 
asd test/test?test.test&test=test 
egd 
test 
3 substitutions occured. 

Hinweis Sie nicht gsub() verwenden, wie dann werden Sie in escaping hell just like if you used sed, statt Sie haben Verwenden Sie index() und substr(), da sie auf Literalfolgen und nicht auf Regexps und Rückreferenzen in den Ersetzungen arbeiten.

Beiseite: immer zitieren Sie Ihre Shell-Variablen und in der Shell Verwendung aller Großbuchstaben ist für exportierte Variablen per Konvention vorbehalten, während sowohl in awk und Shell sollten Sie alle Großbuchstaben Variablennamen sowieso vermeiden, mit integrierten Variablen zu kollidieren.

0

Dies ist meine Lösung durch "sed" Befehl, der genau das tut, was ich brauche. Ich bin mir nicht sicher, wie schnell es laufen wird, da viele Eigenschaften geändert werden müssen, wenn dieses Skript ausgeführt wird.

Jungs bitte eine Bewertung über meine Lösung haben, ist ein konstruktives Feedback willkommen:

PROPERTIES_SOURCE=$SOURCE$PROPERTIES_LOCATION 

MEDIUM=$1 
echo "> Update release for ENVIRONMENT: "$MEDIUM"... Please wait!" 

if [[ -z $1 ]] 
then 
    echo "> [ERROR] - Illegal script use. You have to send one of the following parameters representing environment name which will be updated:" 
    echo "> [ERROR] - DEV ST UAT PROD" 
    echo "> [ERROR] - Example: ./updateEnv.sh PROD" 
    exit 
fi 

nr=1 
while read -r line; do 
    IFS== read -r env prop <<< "$line" 
    if [[ $env == $MEDIUM ]] 
    then 
     IFS== read -r file key value <<< "$prop" 
     if [[ -z $file ]] || [[ -z $key ]] || [[ -z $value ]] 
     then 
      echo "> [ERROR] [LINE $NR] - wrong or missing property: $line" 
     else 
      esc_key=$(echo $key | sed -e 's/\./\\./g') 
      esc_val=$(echo $value | sed -e 's/\&\|\.\|\\\|\/\|\%/\\&/g') 
      occurances=$(grep -c "$key=" "$PROPERTIES_SOURCE$file") 
      if [[ $occurances > 1 ]] 
      then 
       echo "> [WARNING] [LINE $NR] - key found $occurances times: $key" 
      elif [[ $occurances < 1 ]] 
      then 
       echo "> [ERROR] [LINE $NR] - key was not found: $key" 
      fi 
      sed -i "s/${esc_key}=.*/${esc_key}=${esc_val}/g" $PROPERTIES_SOURCE$file 
     fi 
    fi 
    nr=$(($nr + 1)) 
done <$PROPERTIES_LIST 

auch ich mit awk gelang es auch mit einigen sed zu entkommen Strings in meinen Variablen, die von sed anders:

STRING_OLD='asd.asd' 
STRING_NEW='[email protected]#$%^&*()_+-=[]\{}|;"<>~`' 
OLD=$(echo $STRING_OLD | sed -e 's/\./\\\\./g') 
NEW=$(echo $STRING_NEW | sed -e 's/\&\|\\/\\\\&/g') 

Und der Ersatz awk Code so etwas wie dieses würde:

awk -v OLD="$OLD" -v NEW="$NEW" ' 
    BEGIN {print "OLD:"OLD" and NEW:"NEW} 
     ($0 ~ OLD) {gsub(/OLD=.*/,OLD=NEW);}1 
' "$DEST" > "DEST.tmp" mv "DEST.tmp" "$DEST" 
Verwandte Themen