2

Although I've read myself through most of the questions about handling spaces in path names, I haven't found my case yet, which is about several path names in one variable.

find will need this when two base paths are given, for example:

pa="/home/user/folder1 /home/user/folder2"
find $pa -name '*xy*' ... 

This will look for matches in both folder1 and folder2.

(Please note that this is a simplified example; I know very well that in this special case, you could use the -path modifier with a parameter like folder* that spans both folders. However, this question is to cover cases where you cannot work around the issue so easily due to higher complexity.)


Now imagine folder2 contains a space in the middle. The following will not work:

pa="/home/user/folder1 /home/user/fol\ der2"
find $pa -name '*xy*' ... 

The problem is the \, which is normally used to represent a space in the shell but will not work when the variable content is enclosed in double quotes. However, unlike with one path per variable (where it might do the trick), the following won't work either:

pa=/home/user/folder1 /home/user/fol\ der2
find $pa -name '*xy*' ... 

$ ./test.sh: line 3: /home/user/fol der2: Is a directory

nor will the following variant:

pa=/home/user/folder1 /home/user/fol\ der2
find "$pa" -name '*xy*' ... 

So how can spaces be handled properly in paths if several paths are contained in one variable?

Related question: Is there any reliable way at all to determine whether a whitespace is a separator between one path and its successor (within the same variable), or a whitespace that belongs to one of the paths contained within?

1
  • 1
    Well, duplicate or not: I think that in this case, nobody can accuse me of not having searched properly! Plus, I think that users will rather stumble on my question due to it's more descriptive title. On the question linked above, one is rather forced to delve through some remotely related stuff and imagine the rest...*What* you may think is duplicate here, is the section "How do I process a list of file names?". However, I was asking about path names, not file names, that's why chances were high that I wouldn't necessarily stumble on question #131766. Feb 7, 2015 at 17:04

2 Answers 2

5

Use bash arrays:

pa=("/home/user/folder1" "/home/user/fol der2")
find "${pa[@]}" -name '*xy*' ... 

Discussion

Observe that the \ does not do what one hopes:

$ pa="/home/user/folder1 /home/user/fol\ der2"
$ printf '%s\n' $pa
/home/user/folder1
/home/user/fol\
der2

The \ in the definition of pa becomes a literal character in the string, not an escape. If you want a list of separate strings, use an array.

0
0

Use an array variable and put one path value in each element of the array. If that really isn't possible, another approach would be to use something other than space as your item separator.

p[0]="hello"
p[1]="happy"
p[2]="world"

echo "p[0]=${p[0]}, p[1]=${p[1]}, p[2]=${p[2]}"

for p in "${p[@]}"
do
    echo "p=$p."
done

Etc.

Not the answer you're looking for? Browse other questions tagged .