1

I have a small test.sh script as follows:

#!/bin/bash
read -e -p "Enter a Directory: " directory
echo $directory

Here's what happens when I run it:

$ ./test.sh 
Enter a Directory: ~/A\ Directory/
/Users/<username>/A Directory/

I want to be able to keep the escaped space inside that variable so that the program output would read:

$ ./test.sh 
Enter a Directory: ~/A\ Directory/
/Users/<username>/A\ Directory/

Anyone know how to do this? The use for this is to tell the script where to look for files that it needs to read.

Edit: I forgot to put the \ in the second and third code selection.

  • 1
    Are you going to cd the echo output? – snoop Oct 3 '15 at 16:40
  • @snoop I am going to read files from that directory from another directory. – Matthew Sanabria Oct 3 '15 at 18:36
  • You have 2 answers available please see answer section. – snoop Oct 3 '15 at 18:37
0

You could try like this:

Example 1: Your answer.

#!/bin/bash
read -e -p "Enter a Directory: " directory
new_directory="$(echo $directory | sed 's/ /\\ /g')"
echo $new_directory

Example 2: If you are going to cd script output wrap it with double quote.

#!/bin/bash
read -e -p "Enter a Directory: " directory
new_directory=\"$directory\"
echo $new_directory
  • 1
    Both answers seem to work for me. Thank you for your help. – Matthew Sanabria Oct 3 '15 at 18:42
3

There is no escaped space in the variable to keep. When you enter ~/A Directory/ at the prompt, the variable directory contains ~/A Directory/. If you're having trouble with this space later in your script, it's because you forgot the double quotes around variable expansions.

read -e -p "Enter a Directory: " directory
ls -- "$directory"
cd -- "$directory"

The -- is in case the value starts with -, so that it isn't treated as an option.

If for some reason you want to add a backslash before spaces, you can do it with bash's string manipulation features.

echo "${directory// /\\ }"

This is highly unlikely to be useful though. If you need to print out the directory in a form that will be parsed again, there will definitely be other characters to quote. Which characters depends on what's going to parse it, but at the very least tabs (and newlines, but your script is unable to read them) will need quoting if spaces do, and a backslash will also need to be quoted. Bash doesn't have a convenient way to do that. You can use sed, but be careful when passing the data to it — echo does not print all arguments unmodified. An added difficulty command substitution strips trailing newlines, but you won't have newlines here.

quoted_directory=$(printf %s "$directory" | sed 's/[\\ '$'\t'']/\\&/')

Note also that nothing here expands the tilde at the beginning. (The output you show is faked, naughty you!) Tilde expansion only happens as part of source code parsing, it does not happen when the value of a variable is expanded. If you want to replace an initial tilde with the home directory, you'll need to do it manually.

read -e -p "Enter a Directory: " directory
if [[ $directory = \~/* ]]; then
  directory="$HOME/${directory#*/}"
fi
ls -- "$directory"
cd -- "$directory"
  • Please see my edit above. I want to be able to enter a directory in the form of ~/A\ Directory/ and be able to use that directory normally without the space causing a break in cd or ls commands. In my particular case I am telling the script where it will look for files to read. – Matthew Sanabria Oct 4 '15 at 0:32
  • @MatthewSanabria I'm confused now: do you want to remove the backslash that you typed? Keep in mind that in your tests, you are not printing the value of the variable: you're splitting it, doing globbing on it, and then letting echo mangle it further. To print the exact value of a variable, use printf %s "$directory". If you want a newline after it, use printf '%s\n' "$directory". If you want to use what you typed unmodified, I've given snippets to do that in my answer. – Gilles Oct 4 '15 at 13:07
  • I want to be able to have the script ask a user for a directory. The user should be able to use the tab key to auto complete the directory name. That would result in "~/A\ Directory" if the directory had a space in the name. I want to be able to keep that directory name in a variable that I can use to read files from and/or use cd and ls. – Matthew Sanabria Oct 4 '15 at 14:16
  • 1
    @MatthewSanabria Actually, read performs backslash expansion on its input (because you didn't pass -r), so what you get in the variable is the right form to pass to cd except that completion allows an initial ~. There is no backslash in the value of the variable, and you must not have a backslash there to pass it to cd (unless the name of the directory contains a backslash of course). So my last snippet will work for you. Once again, keep in mind that echo $directory does NOT print the value of the variable directory; you need printf '%s\n' "$directory" for that. – Gilles Oct 4 '15 at 14:31
  • Thank you for the quick replies. I will try your snippets when I get home later and update the post. – Matthew Sanabria Oct 4 '15 at 14:33
0

Per https://askubuntu.com/a/344418,

Clear the IFS variable thusly:

   IFS=$'\n'       # make newlines the only separator

Then continue your script.

  • 1
    This is good for looping, but in my case I am not using any loops. I'll keep this link as a reference though. – Matthew Sanabria Oct 3 '15 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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