Question

I am trying to read lines within a file and if the line contains a tag, the text within the tag is used to replace the tag with a value from a different propertiesfile, before the line, with all tags replaced is written to a different file.

So the initial file being read have lines that would adhere to the following format:

testkey "TEST-KEY" "[#key_location#]:///[#key_name#]"

Where [# and #] house the tag text.

The propertied file would then contain lines like:

key_location=location_here
key_name=test_key_name

So the end result I am trying to achieve is that the line is written to a new file, but the tags are replaced with the values from the property file, so using the above content:

testkey "TEST-KEY" "loaction_here:///test_key_name"

I am not sure how best to handle the tags and deal with multiple tags in one line and am pretty lost. Any help would be greatly appreciated.

Skeleton code:

while read line

    if [[ $line == *[#* ]]
    then
       #echo found a tag and need to deal with it





    else

        echo "$line">> $NEW_FILE
    fi

   done < $INITIAL_FILE

EDIT

Lines within the file could contain one or more tags, not always two like in the example given.

Was it helpful?

Solution

You'll have to do some looping and global sed replacements. The following is probably not optimal but it will get you started:

#!/bin/bash

declare -A props
while read line ; do
    key=$(echo $line | sed -r 's/^(.*)=.*/\1/')
    value=$(echo $line | sed -r 's/^.*=(.*)/\1/')
    props[$key]=$value
done < values.properties

replace() {
    line=$1
    for key in "${!props[@]}"; do 
        line=$(echo $line | sed "s/\[#$key#\]/${props[$key]}/g")
    done
    echo $line
}

while read line ; do
    while [[ $line == *"[#"*"#]"* ]] ;do
        line=$(replace "$line")
        echo Iter: $line
    done
    echo DONE: $line
done < $INITIAL_FILE

The snippet prints to stdout and it includes intermediate results so that you can check how it works. I think you will easily be able to modify it to write to a file, etc.

OTHER TIPS

There are a number of ways to do this (e.g. count #). But simply, you can just use * expansion outside just the start and end of the string so

if [[ $line == *"[#"*"#]"*"[#"*"#]"* ]]; then 
  echo "has tags"
else 
  echo "does not have tags" 
fi

Would work in your case, e.g.

$ echo "$line" 
testkey "TEST-KEY" "[#key_location#]:///[#key_name#]"
$ if [[ $line == *"[#"*"#]"*"[#"*"#]"* ]]; then echo "has tags"; fi
has tags
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top