I have a text file where I want to make a text replacements using another file, which is structured like that:
key1=value1
key2=value2
...
I am using a bash script for that and I end up with the following solution:
#!/bin/bash
index=0
count=$(wc -l $2 | grep -Eo '[0-9]')
until [ $index -eq $count ]; do
line=$(awk "NR==($index 1)" $2)
key=$(echo $line | cut -f1 -d=)
value=$(echo $line | cut -f2 -d=)
sed -i '' 's/'"${key}"'/'"${value}"'/g' $1
index=$(($index 1))
done
Basically I am getting number of lines in the mapping file and just iterating through it, splitting each line by a =
sign and calling a sed
command. This works fine and does its job, but I wanted to ask if there is a more efficient way to achieve that? Since I am not a big bash expert, I assume that there might be better/more beautiful approach.
CodePudding user response:
This might work for you (GNU sed):
sed -nE 's#(.*)=(.*)#s/\1/\2/#p' inputFile | sed -f - textFile
Convert the input file into a source of a sed file and pipe it into a second invocation of sed to be acted on a text file.
N.B. Your success may vary if either the key or the value contain characters that may be mistook for sed's metacharacters e.g. contain a $
or .
etc etc etc.
CodePudding user response:
Generate a sed script from the file just as is, by prepending with s/
, changing =
to /
and suffixing with /g
. Then run the generated sed script over the input file.
sed "$(sed 's/\(.*\)=\(.*\)/s\/\1\/\2\/g/' "$another_file")" "$text_file"
If you are creating templates, this is not a good approuch, in such case go with a template or preprocessor engine - like envsubst
, cpp
, php
, jinja2
.
Remember to check your scripts with shellcheck.
I am getting number of lines in the mapping file and just iterating through it, splitting each line by a = sign