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

362
Darren

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

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

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

1

3 ответа на вопрос

4
Eric Renouf

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

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

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

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

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

3
Kamil Maciorowski

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

for pic in * ; do … 

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

Да, это работает лучше, спасибо! В конечном итоге я пытался объединить вывод в команду find для поиска дубликатов, и это не работало, пока я не использовал ваш метод. Darren 6 лет назад 0
1
Darren

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

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

Похожие вопросы