1

I have a directory of photos whose names are the time and date the photo was taken. E.g:

~$ ls directory -1
2003-09-15 03.30.33.jpg
2004-05-04 12.45.28.jpg
2004-05-04 12.45.51.jpg

However, if I run this command as part of a for loop, and echo the output, the spaces in the filenames are treated as new lines:

~$ for pic in `ls directory -1` ; do echo  "$pic"; done
2003-09-15
03.30.33.jpg
2004-05-04
12.45.28.jpg
2004-05-04
12.45.51.jpg

Why is this happening, and how can I stop it?

3 Answers 3

4

As the other answers intimate, the problem is how the loop is processing the output of the ls command. When a string is used in the for loop as you have it, the string gets split into different words (based on the value of IFS as Darren says), and subject to globbing and the like. That means that you are passing a string that gets split both by the line and the spaces within the line, then each of those words in turn gets set in pic.

Kamil's suggestion solves this problem because you let the glob expand to all the file names directly, and the entire filename is then assigned to pic.

That word splitting will happen anywhere that you use the pic variable later though, so if you do not want that to happen be sure to put double quotes around it. E.g.,

for pic in *; do
    printf '%s\n' "$pic"
done

to print each of the names, one per line.

3

In your case plain shell globbing may be enough:

for pic in * ; do …

This way you also avoid parsing ls which is in general not a good idea.

1
  • Yes, this is working better thanks! I was ultimately trying to plumb the output into a find command to search for duplicates and that wasn't working either until I used your method.
    – Darren
    Commented Jun 8, 2017 at 15:21
1

Question answered here. The short answer is to run this command:

IFS=$(echo -en "\t\n\0")

You must log in to answer this question.

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