Почему выходные данные этой команды echo перебегают в несколько строк?

У меня есть каталог фотографий, чьи имена являются временем и датой, когда была сделана фотография. Например:

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

Тем не менее, если я запускаю эту команду как часть for Зацикливание и вывод результатов, пробелы в именах файлов обрабатываются как новые строки:

~$ 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

Почему это происходит, и как я могу это остановить?

3 ответа

Решение

Поскольку другие ответы близки, проблема в том, как цикл обрабатывает выходные данные ls команда. Когда строка используется в for цикл, как у вас есть, строка разбивается на разные слова (в зависимости от значения IFS как говорит Даррен), и подвержены болтовне и тому подобное. Это означает, что вы передаете строку, которая разделяется как на строку, так и на пробелы в строке, затем каждое из этих слов в свою очередь устанавливается в pic,

Предложение Камиля решает эту проблему, потому что вы позволяете глобусу расширяться до всех имен файлов напрямую, а затем все имя файла присваивается pic,

Это разделение слов произойдет везде, где вы используете pic переменная позже, поэтому, если вы не хотите, чтобы это произошло, обязательно поставьте двойные кавычки вокруг него. Например,

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

напечатать каждое из имен, по одному в строке.

В вашем случае может быть достаточно простой оболочки:

for pic in * ; do …

Таким образом, вы также избегаете разбора ls что в целом не очень хорошая идея.

На вопрос ответили здесь. Краткий ответ - запустить эту команду:

IFS=$(echo -en "\t\n\0")
Другие вопросы по тегам