简体   繁体   中英

shell script to read values from one file and replace it in other file

I would like to replace a set of strings into a new file. Source file file1.json values has to be replaced by values from file1.config into file file2.json. I have following script that is failing to do so.

file1.json

{
    "colorsArray":[{
            "red":"$ALERT_LEVEL",
            "green":"$NORMAL_LEVEL",
            "blue":"$RELAX_LEVEL"
        }
    ]
}

file1.config

[root@ip10]# cat file1.config
ALERT_LEVEL=DANGER
NORMAL_LEVEL=NORMAL
RELAX_LEVEL=RELAX

run.sh

    #!/bin/bash
set -x
if [ $# -ne 3 ]; then
  echo "USAGE:
        ./$0 file1.json file2.json file1.config"
  exit 1
fi
echo "#!/bin/bash
cat > $2 << EOF
`cat $1`
EOF" > $2;
chmod +x $2;
# load variables into env
. $3
# actually replace variables
./$2

Error:

[root@ip10]# ./run2.sh file1.json file2.json file1.config
./file2.json: line 11: warning: here-document at line 2 delimited by end-of-file (wanted `EOF')

file2.json appears, but it has no values replaced.

root@ip10]# cat file2.json 
    {
        "colorsArray":[{
                "red":"",
                "green":"",
                "blue":""
            }
        ]
    }

Just explaining the comment of @user3159253. Your file1.config should look like this for your code to work properly:

export ALERT_LEVEL=DANGER
export NORMAL_LEVEL=NORMAL
export RELAX_LEVEL=RELAX

PS IMHO the way you do the thing is a bit overelaborate. I'd prefer using sed to complete this task -- takes only one string:

sed file1.json -e 's/$ALERT_LEVEL/DANGER/g' -e's/$NORMAL_LEVEL/NORMAL/g' -e's/$RELAX_LEVEL/RELAX/g' >file2.json

This is the classic problem of reading env vars from a file, and substituting those values in another file. There is an inherent danger is using eval with your input file, so that should be avoided.

The simplest way is if your system already has the command envsubst , which does this for you. Usage:

$ var1=value1 var2=value2 envsubst < input.txt > output.txt

The trick here, though, is that your env vars are in another text file. So they aren't specified on the command line itself; they'll need to be export ed to be seen by envsubst . Eg,

#!/bin/bash
export var1=value1
export var2=value2
envsubst < input.txt > output.txt

Here's one possible way to do this with an input file of env vars:

#!/bin/bash
eval $(sed 's/^.*=/export &/' file1.config)
envsubst < file1.json > file2.json

If you don't have envsubst available, then see this answer for other options (eg, eval , sed , m4 , ...): How to replace ${} placeholders in a text file?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM