Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escaping dots in bash variables

Tags:

bash

shell

I want to escape dots from an IP address in Unix shell scripts (bash or ksh) so that I can match the exact address in a grep command.

echo $ip_addr | sed "s/\./\\\./g"

works (outputs 1\.2\.3\.4), but

ip_addr_escaped=`echo $ip_addr | sed "s/\./\\\./g"`
echo $ip_addr_escaped

Doesn't (outputs 1.2.3.4)

How can I correctly escape the address?

Edit: It looks like

ip_addr_escaped=`echo $ip_addr | sed "s/\./\\\\\\\./g"`

works, but that's clearly awful!

like image 351
Tim Bellis Avatar asked Feb 21 '13 14:02

Tim Bellis


People also ask

How do you escape special characters in variable Bash?

Bash Character Escaping. Except within single quotes, characters with special meanings in Bash have to be escaped to preserve their literal values. In practice, this is mainly done with the escape character \ <backslash>.

How do you escape a dot in shell script?

The commandline is interpreted by the shell, using the first \ to escape the second one, so one \ is passed literally to grep. The dot . is not special to the shell, so it is passed verbatim anyway. Grep then reads the (single) \ and uses it to escape the dot . .

What does [- Z $1 mean in Bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.

What's do `` $() ${} commands do in Bash?

Save this answer. Show activity on this post. $() means: "first evaluate this, and then evaluate the rest of the line". On the other hand ${} expands a variable.


3 Answers

bash parameter expansion supports pattern substitution, which will look (slightly) cleaner and doesn't require a call to sed:

echo ${ip_addr//./\\.}
like image 82
chepner Avatar answered Sep 24 '22 00:09

chepner


Yeah, processing of backslashes is one of the strange quoting-related behaviors of backticks `...`. Rather than fighting with it, it's better to just use $(...), which the same except that its quoting rules are smarter and more intuitive. So:

ip_addr_escaped=$(echo $ip_addr | sed "s/\./\\\./g")
echo $ip_addr_escaped

But if the above is really your exact code — you have a parameter named ip_addr, and you want to replace . with \. — then you can use Bash's built-in ${parameter/pattern/string} notation:

ip_addr_escaped=${ip_addr//./\\.}

Or rather:

grep "${ip_addr//./\\.}" [FILE...]
like image 36
ruakh Avatar answered Sep 23 '22 00:09

ruakh


Replace the double quotes with single quotes.

like image 45
Jonas Berlin Avatar answered Sep 26 '22 00:09

Jonas Berlin