为什么这个 echo 命令的输出超出了多行?

为什么这个 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

为什么会发生这种情况?我该如何阻止它?

答案1

正如其他答案所暗示的那样,问题在于循环如何处理命令的输出ls。当在for循环中使用字符串时,该字符串会被拆分为不同的单词(基于IFSDarren 所说的值),并进行通配符等。这意味着您传递的字符串会被行和行内的空格拆分,然后每个单词依次设置为pic

Kamil 的建议解决了这个问题,因为您让 glob 直接扩展为所有文件名,然后将整个文件名分配给pic

不过,该单词拆分将在您pic稍后使用该变量的任何地方发生,因此如果您不希望发生这种情况,请确保在其周围加上双引号。例如,

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

打印每个名称,每行一个。

答案2

在你的情况下,简单的 shell 通配符可能就足够了:

for pic in * ; do …

这样,你还可以避免ls通常的解析不是一个好主意

答案3

问题解答这里。简短的回答是运行这个命令:

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

相关内容