Sending bash script variables to sed
first time poster here and I searched for quite some time but didn't find a thread I could understand well enough to solve my problem.
I have a loop in my script that generates certain variables via cut -d delimitation and I wan to use that variables as input for sed to alter a file differntly each iteration. My current script is:
My current script looks like:
for input in $(tail -n 3 filea)
do
a="$(echo $input | cut -d "," -f 1)"
b="$(echo $input | cut -d "," -f 2)"
c="$(echo $input | cut -d "," -f 3)"
echo $a
echo $b
echo $c
tail -n 1 fileb | sed 's,'$a','$c',2'
done
With an output of:
K
26
T
KTTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
P
27
E
KKTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
S
31
P
KKTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Where for example the string on position 31 should be replaced with S if it is P.
My current status is that I get the variables a and c correctly transfered into the sed command and respective strings get replaced but changing it to sed 's,'$a','$c','$b''
stops any replacement and the native (last) line of fileb gets prompted.
I know that asking a good question is a whole other topic, but I hope somebody can help me to understand the writing here so I can continue to learn programming as I often step over mistakes like these.
Notes:
- don't use
for
for reading lines of a file - use
IFS
andread
to split a line using a separator - be more rigourous about quoting variables.
Given:
$ cat filea
K,26,T
P,27,E
S,31,P
$ cat fileb
-------------------------TE---P---
then
tail -n 3 filea | while IFS=, read -r replacement position character; do
printf -v regex '^(.{%d})%s' $((position - 1)) "$character"
printf -v repl '\\1%s' "$replacement"
echo "$regex"
echo "$repl"
tail -n 1 fileb
tail -n 1 fileb | sed -E "s/$regex/$repl/"
done
outputs:
^(.{25})T
\1K
-------------------------TE---P---
-------------------------KE---P---
^(.{26})E
\1P
-------------------------TE---P---
-------------------------TP---P---
^(.{30})P
\1S
-------------------------TE---P---
-------------------------TE---S---
But, this is something that bash can do without sed, using the ${var:offset:length}
form of Parameter Expansion:
tail -n 3 filea | while IFS=, read -r replacement position character; do
echo "$replacement $position $character"
line=$(tail -n 1 fileb)
echo "$line"
if [[ "${line:position - 1:1}" == "$character" ]]; then
line=${line:0:position - 1}${replacement}${line:position}
fi
echo "$line"
done
outputs
K 26 T
-------------------------TE---P---
-------------------------KE---P---
P 27 E
-------------------------TE---P---
-------------------------TP---P---
S 31 P
-------------------------TE---P---
-------------------------TE---S---