Bash – How to escape special characters in a string

bash

Assuming $file holding a value of a file name, say Dr' A.tif. In bash programming, how could I escape single quote and any other special character of the $file without removing the special character?

Update on 9 July 2014

As request from @Gilles, following code snippet that doesn't able to handle Dr' A.tif:

files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]")
echo "${files}" > ${TEMP_FILE}
while read file
do
   newfile=$(echo "${file}" | sed 's, ,\\ ,g') ## line 1
done < ${TEMP_FILE}

After I have tried out the answer from @Patrick on line 1, it seems to work for me. But if I have file such as Dr\^s A.tif, printf command doesn't seem help, it shows me Dr\^s\ A.tif. If I manually try it on console like this:

printf "%q" "Dr\^s A.tif"

I will have this output:

Dr\\\^s\ A.tif

Any idea how to handle this?

Best Answer

You can use the printf builtin with %q to accomplish this. For example:

$ file="Dr' A.tif"
$ printf '%q\n' "$file"
Dr\'\ A.tif

$ file=' foo$bar\baz`'
$ printf '%q\n' "$file"
\ foo\$bar\\baz\`

From the bash documentation on printf:

In addition to the standard format specifications described in printf(1)
and printf(3), printf interprets:

 %b       expand backslash escape sequences in the corresponding argument
 %q       quote the argument in a way that can be reused as shell input
 %(fmt)T  output the date-time string resulting from using FMT as a format
          string for strftime(3)
Related Question