2

I have text like: TEXT="I need to replace the hostname [[google.com]] with it's ip in side the text"

Is there a way to use something like below, but working? sed -Ee "s/\[\[(.*)\]\]/`host -t A \1 | rev | cut -d " " -f1 | rev`/g" <<< $TEXT

looks like the value of \1 is not being passed to the shell command used inside sed.

Thanks

Sergey I
  • 23
  • 4

4 Answers4

1

Backquote interpolation is performed by the shell, not by sed. This means that your backquotes will either be replaced by the output of a command before the sed command is run, or (if you correctly quote them) they will not be replaced at all, and sed will see the backquotes.

You appear to be trying to have sed perform a replacement, then have the shell perform backquote interpolation.

You can get the backquotes past the shell by quoting them properly:

$ echo "" | sed -e 's/^/`hostname`/'
`hostname`

However, in that case you will have to use the resulting string in a shell command line to cause backquote interpolation again.

Depending on how you feel about awk, perl, or python, I'd suggest you use one of them to do this job in a single pass. Alternatively, you could make a first pass extracting the hostnames into a command without backquotes, then execute the commands to get the IP addresses you want, then replace them in another pass.

aghast
  • 14,785
  • 3
  • 24
  • 56
1

It's got to be a two part command, one to get a variable that bash can use, the other to do a straight-up /s/ replacement with sed.

TEXT="I need to replace the hostname [[google.com]] with it's ip in side the text"
DOMAIN=$(echo $TEXT | sed -e 's/^.*\[\[//' -e 's/\]\].*$//')
echo $TEXT | sed -e 's/\[\[.*\]\]/'$(host -tA $DOMAIN | rev | cut -d " " -f1 | rev)'/'

But, more cleanly using how to split a string in shell and get the last field

TEXT="I need to replace the hostname [[google.com]] with it's ip in side the text"
DOMAIN=$(echo $TEXT | sed -e 's/^.*\[\[//' -e 's/\]\].*$//')
HOSTLOOKUP=$(host -tA $DOMAIN)
echo $TEXT | sed -e 's/\[\[.*\]\]/'${HOSTLOOKUP##* }/

The short version is that you can't mix sed and bash the way you're expecting to.

Jeff Breadner
  • 1,366
  • 9
  • 19
0

This works:

#!/bin/bash

txt="I need to replace the hostname [[google.com]] with it's ip in side the text"
host_name=$(sed -E 's/^[^[]*\[\[//; s/^(.*)\]\].*$/\1/' <<<"$txt")
ip_addr=$(host -tA "$host_name" | sed -E 's/.* ([0-9.]*)$/\1/')
echo "$txt" | sed -E 's/\[\[.*\]\]/'"$ip_addr/"

# I need to replace the hostname 172.217.4.174 with it's ip in side the text
dawg
  • 98,345
  • 23
  • 131
  • 206
0

Thank you all,

I made the below solution:

function host_to_ip () {
    echo $(host -t A $1 | head -n 1 | rev | cut -d" " -f1  | rev)
}

function resolve_hosts () {
    local host_placeholders=$(grep -o -e "##.*##" $1)

    for HOST in ${host_placeholders[@]}
    do
        sed -i -e "s/$HOST/$(host_to_ip $(sed -Ee 's/##(.*)##/\1/g' <<< $HOST))/g" $1 
    done
 }

Where resolve_hosts gets a text file as an argument

Sergey I
  • 23
  • 4