Don't parse the output of ls
. You don't need ls
to list the contents of a directory: you can use shell wildcards instead.
When you write $(ls $LOCATION)
, the output from the ls
command is split into separate words wherever it contains whitespace. That's why your command mangled file names with spaces. You can modify the IFS
variable to avoid having spaces considered separators, but there's no way to distinguish between a newline that separates file names from a newline within a file name, so you can't avoid trouble completely. Furthermore, each word that results from the split is treated as a glob (i.e. a wildcard pattern) and replaced by the list of matching files, if any. A simple rule of shell scripting is: always put double quotes around variable substitutions "$foo"
and command substitutions "$(foo)"
. The double quotes prevent the splitting and globbing.
The following snippet is equivalent to your loop, except that it doesn't mangle file names, and it prints the full path to each file.
for x in "$LOCATION"/*; do
echo "$x"
done
If you want the path relative to $LOCATION
, one way is to change to the target directory first.
cd "$LOCATION"
for x in *; do
echo "$x"
done
Another way is to strip off the prefix from the file name.
for full_path in "$LOCATION"/*; do
relative_name=${full_path#"$LOCATION/"}
echo "$relative_name"
done
This prints the name of all files in the target directory. If you only want to list subdirectories (including symbolic links to directories), add a /
to the glob pattern to constrain the matches.
for full_path in "$LOCATION"/*/; do
relative_name=${full_path#"$LOCATION/"}
relative_name=${relative_name%/}
echo "$relative_name"
done
If you don't want symlinks to be included, make an explicit test for a directory within the loop.
for full_path in "$LOCATION"/*/; do
if ! [ -d "$full_path" ]; then continue; fi
relative_name=${full_path#"$LOCATION/"}
relative_name=${relative_name%/}
echo "$relative_name"
done
basename "$folder"
. – Lekensteyn Dec 13 '12 at 17:03while read
loops, which should be writtenwhile IFS= read -r folder;
. – Gilles 'SO- stop being evil' Dec 13 '12 at 23:07