Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

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
   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?

share|improve this question
in what context are you expecting to use $file? or is this issue assigning the string with the special character to $file? –  rob Jul 8 '14 at 10:50
Actually the find command return me an array of file list. And then I loop through this file list into $file variable. –  huahsin68 Jul 8 '14 at 10:56
You've been given some correct answers here, but they are probably not the answers to the question that you're really asking. From your comment here, I strongly suspect that you're on the wrong track. We can't help you much because you keep not showing your code. I do however recommend that you read Why does my shell script choke on whitespace or other special characters? as background. Show your script and explain what you want to do. –  Gilles Jul 8 '14 at 21:18

4 Answers 4

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)
share|improve this answer

You don't need to escape any file names you are handling in a script. Escaping is only necessary if you want to put a file name as a literal in a script, or to pass several file names as a single input stream to another script.

Since you're looping through the output of find, this is one of the simplest ways (!) to handle every possible path:

while IFS= read -r -d ''
    file_namex="$(basename -- "$REPLY"; echo x)"
    do_something -- "$file_name"
done <(find "$some_path" -exec printf '%s\0' {} +)
share|improve this answer


file=Dr\'\ A.tif
echo $file
Dr' A.tif


file="Dr' A.tif"
echo $file
Dr' A.tif

or if the string contains a double quote:-

file='Dr" A.tif'
echo $file
Dr" A.tif

There are good tutorials on escaping and quoting on the net. Start with this one.

share|improve this answer

quick and (very) dirty

find . | sed 's/^/"/' | sed 's/$/"/'
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.