Skip to content
Advertisement

Replace variable in text file with another variable

I am trying to write a variable to a specific spot in a text file.

So far I have the variable generation part done, but when I open the text file to see the result, the ${at} placeholder has been replaced with ${assetTag} and not the value of the variable.

set -x # Print each line of script

set -e # Print error codes for debugging

serialNum=$(dmidecode -s chassis-asset-tag) 

assetTag=$(awk -e '$1 == "'"$serialNum"'"{print $2; q}' /tmp/AssetTag.txt)

cat /tmp/BIOS.txt | sed -e "s/{$aT}/$assetTag/" >> /tmp/BIOS.txt

exit  0

So the idea is that I compare the $serialNum to a file containing Serial Numbers and Asset Tags. From there I write the corresponding Asset Tag to $assetTag. After that I need to replace the $aT placeholder in the Text file with the $assetTag value and save the file for uploading into the system.

BIOS.txt excerpt

... <br>
Asset Tracking Number <br>
    ${aT} <br>
Ownership Tag <br>

Product Name <br>
    Thin Client <br>
...<br>


BIOS.txt excerpt after running script

... <br>
Asset Tracking Number <br>
    ${assetTag} <br>
Ownership Tag <br>

Product Name <br>
    Thin Client <br>
...<br>

Edit:

Part of the reason I am trying to edit the file is that the script engine I am using has a max of 4096 characters. In the past I did a “cat >/tmp/Rename.txt << EOL” and simple wrote out the entire file in the script engine. That however puts me at the limit so I have no more space to add code. So, if I can edit an existing file that I copied to the Thin Client… I can save lines in the script for actual code and not file construction.

Edit:

Ok, so I found a carriage return at the end of the Asset Tag in the Asset_Tag.txt file. so that is causing the current headache.

assetTag=$(awk -e '$1 == "'"$serialNum"'"{print $2; q}' /tmp/AssetTag.txt)

sed -e "s/@aT@/$assetTag/" /tmp/T630_BIOS.txt > /tmp/BIOS.txt

So the question is do I need a tr -d 'r' somewhere. In the assetTag declaration?

Advertisement

Answer

This is a dangerous operation:

cat file | cmd >> file

It will both open the file for reading and modifying. If the OS didn’t stop you, it would be an endless loop (cat reading something, cmd adding to the file, cmd reading that new input …).

I would suggest that you write the output to a new file to avoid all kinds of weird problems.

That said, the pattern {$aT} will never match the input ${aT}. To match the input, you need this regexp: ${aT} but you’re using double quotes, so BASH might eat the backslash before sed can see it. Check the debug output which set -x provides. Make sure the backslash is still there. If it doesn’t work, try \${aT} or single quotes – but single quotes will mess with expanding $assetTag, so you’ll need the same double-single-quote trick which you used in the awk script.

That’s why many BASH-based template engines use a different prefix like @ instead of $: @aT@ (no curly braces) or @{aT}

Or this might be even more simple:

cat header.tmpl > /tmp/BIOS.txt
echo "$assetTag" >> /tmp/BIOS.txt
cat footer.tmpl >> /tmp/BIOS.txt

i.e. instead of complex sed scripts, just build the output from fragments.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement