Home > Software engineering >  sed replace key that begin in file with long text that include key and value
sed replace key that begin in file with long text that include key and value

Time:01-19

in kafka.properies file

more /home/kafka.properies
log.retention.hours=12
delete.topic.enable=true
leader.imbalance.check.interval.seconds=300
leader.imbalance.per.broker.percentage=10
log.dir=/var/kafka/data1

we want to replace the

log.dir=/var/kafka/data1

or any combination as

log.dir=/var/kafka/data1,/var/kafka/data2, ...... 

with $line

when:

echo $line
/var/kafka/data1,/var/kafka/data2,/var/kafka/data3,/var/kafka/data4,/var/kafka/data5,/var/kafka/data6,/var/kafka/data7,/var/kafka/data8

so we did the following:

 sed "s/^log.dir.*/\$line/g"   /home/kafka.properies

or

sed 's/^log.dir.*/$line/g'   /home/kafka.properies

but we get

log.retention.hours=12
delete.topic.enable=true
leader.imbalance.check.interval.seconds=300
leader.imbalance.per.broker.percentage=10
$line

instead to get

log.retention.hours=12
delete.topic.enable=true
leader.imbalance.check.interval.seconds=300
leader.imbalance.per.broker.percentage=10
log.dir=/var/kafka/data1,/var/kafka/data2,/var/kafka/data3,/var/kafka/data4,/var/kafka/data5,/var/kafka/data6,/var/kafka/data7,/var/kafka/data8    
 

where I am wrong? , what is the right approach for this replacing ? ( with sed or perl one liner or other )

CodePudding user response:

You need to use

sed "s~^log\.dir.*~log.dir=$line~" /home/kafka.properies

If there are any leading whitespaces, you may try

sed "s~^ *log\.dir.*~log.dir=$line~" /home/kafka.properies # only spaces
sed "s~^[[:space:]]*log\.dir.*~log.dir=$line~" /home/kafka.properies # any whitespaces
sed "s~^\s*log\.dir.*~log.dir=$line~" /home/kafka.properies # GNU sed only

See the online demo:

#!/bin/bash
s='log.retention.hours=12
delete.topic.enable=true
leader.imbalance.check.interval.seconds=300
leader.imbalance.per.broker.percentage=10
log.dir=/var/kafka/data1'
line='/var/kafka/data1,/var/kafka/data2,/var/kafka/data3,/var/kafka/data4,/var/kafka/data5,/var/kafka/data6,/var/kafka/data7,/var/kafka/data8'
sed "s~^log\.dir.*~log.dir=$line~g" <<< "$s"

Ouitput:

log.retention.hours=12
delete.topic.enable=true
leader.imbalance.check.interval.seconds=300
leader.imbalance.per.broker.percentage=10
log.dir=/var/kafka/data1,/var/kafka/data2,/var/kafka/data3,/var/kafka/data4,/var/kafka/data5,/var/kafka/data6,/var/kafka/data7,/var/kafka/data8

Note:

  • ~ is used as a regex delimiter char here since the replacement contains / chars
  • . in log.dir must be escaped to match a literal . char, else, . matches any single char
  • You need to use double quotation marks in the sed command to be able to use variables in it.
  • Since you match log.dir and consume it, this text will be removed from the match, and you should put it back in the replacement pattern.

As an option, you can capture the log.dir and use the backreference/placeholder to the group value in the RHS:

sed -E "s~^(log\.dir=).*~\1$line~" /home/kafka.properies
  •  Tags:  
  • Related