Home > Software engineering >  Replace a text in the file from the key value pairs in bash
Replace a text in the file from the key value pairs in bash

Time:04-26

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

Research https://mywiki.wooledge.org/BashFAQ/001

  • Related