1

I'm trying to parse through a set of files in a directory on a mapped drive. However, I can't seem to resolve an issue that seems to be because of spaces in the path to the subdirectory. Would appreciate any help! Thank you.

#!/bin/bash
FILES=/home/user/.gvfs/analysis\$\ on\ server.university.edu/users/username/m/BED_files/*
#FILES=/home/user/Desktop #this works

for f in "${FILES}"
do
    echo $f
done
Random832
  • 10,666
Stephen
  • 141

3 Answers3

2

You can't use the wildcard as part of the variable if you are also using quotes. Note that in the array variable syntax @jasonwryan suggested, it is looking at the contents of the directory at the time the array is initialized, rather than when the loop is executed.

#!/bin/sh
DIR='/home/user/.gvfs/analysis$ on server.university.edu/users/username/m/BED_files'

for f in "$DIR"/*
do
    echo "$f"
done

If you really need the wildcard to be defined in a variable, putting it it in a separate one will work:

#!/bin/sh
DIR='/home/user/.gvfs/analysis$ on server.university.edu/users/username/m/BED_files'
FILES='*.txt'

for f in "$DIR"/$FILES
do
    echo "$f"
done
Random832
  • 10,666
0

Verify that you have permissions all the way through to the final subdirectory and @jasonwryan answer should work.

0

If you want to work with an arrayed expansion result in a basic POSIX shell you have to take care with both $IFS and filename generation. You can work safely with unquoted variables - but it is usually not the most simple way to do it.

Shell's are designed to work first and foremost with arguments - so I suggest you use the argument array:

set -- "${FILES%/*}"/*

You'll have to check a glob's result though - in any POSIX shell if the glob doesn't resolve it will still remain an iterable parameter. This is true of for var in glob* as well - without testing the results you cannot be sure that you're actually working with a file. So...

for f do [ -e "$f" ] || [ -L "$f" ] && printf %s\\n "$f"; done

You can iterate over the items in your arg array like for arg do ...;done. You can also address them from within the loop as "$1" "$2" and etc, or as a whole with either of "$@" and "$*" depending. The array remains set when the loop is complete.

One last note though, as I mentioned before, filename generation is a configurable feature of the shell. It can be disabled w/ set -f or enabled w/ set +f. What's more, it only works if there are matching filenames in the directory in which you search - if there are none, you just get your unresolved glob back. Globbing also requires both search and execute permissions for a directory. So, if you find you cannot resolve a glob match, you might try enabling filename generation, checking the path's permissions, and verifying there are files there in the first place.

mikeserv
  • 58,310
  • bash bash the shopt -s nullglob option which is handy to replace the pattern with nothing if there are no matches. For ksh93, use ~(N)pattern* for the same effect. – glenn jackman Feb 24 '15 at 19:01
  • This set -- 1 2 3 4; for arg do; echo $arg; done (without a semicolon before "do") throws an error in bash and dash. It iterates properly in ksh and zsh. – glenn jackman Feb 24 '15 at 19:10
  • OK, I've been schooled. Apologies for the hard-headedness. – glenn jackman Feb 25 '15 at 02:46
  • @glennjackman - no sweat - there was no offense taken here - i like talking about that stuff. And if you don't get a little learning at the answers site every once in a while, it might be hard to justify coming back. Anyway, i like that form because I like being able to refer to the arg array as whole before, after, and during - and numbered is just easier for me. I also like changing the array while I iterate - doing for arg do set inner loop arg array is just fine. There are probably better links on the subject, but this one is ok – mikeserv Feb 25 '15 at 03:10