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.