如何使用 打印每行一个文件/目录列表echo
?
我可以用换行符替换空格,但如果文件名包含空格,则这不起作用:
$ echo small*jpg
small1.jpg small2.jpg small photo 1.jpg small photo 2.jpg
$ echo small*jpg | tr ' ' '\n'
small1.jpg
small2.jpg
small
photo
1.jpg
small
photo
2.jpg
我知道我可以使用 来做到这一点ls -d1
,但是也可以使用 来做到这一点吗echo
?
答案1
echo
无论如何都不能用于输出任意数据,请使用printf
使用echo
这是用于输出文本的损坏实用程序的 POSIX 替代品。
printf '%s\n' small*jpg
您还可以这样做:
printf '%s\0' small*jpg
以 NUL 分隔记录的形式输出列表(因此可以对其进行后处理;例如使用 GNU xargs -r0
;请记住换行符与空格或文件名中的任何字符一样有效)。
在 POSIX 出现之前printf
,ksh 已经有一个print
实用程序可以替代echo
。 zsh 复制了它并添加了一个-l
选项来每行打印一个参数:
print -rl -- small*jpg
ksh93 添加了一个类似打印的-f
选项。也被复制,但不被其他 ksh 实现复制:print
printf
zsh
print -f '%s\n' -- small*jpg
请注意,如果没有给出任何参数,所有这些函数仍会打印一个空行。更好的方法println
是将其写成如下函数:
println() {
[ "$#" -eq 0 ] || printf '%s\n' "$@"
}
在zsh
:
println() print -rC1 -- "$@"
答案2
echo
仅使用空格来分隔作为参数接收的字符串。
由于您的问题已被标记巴什,这里是说help echo
的bash
(强调我的):
显示 ARG,由单个空格字符分隔然后在标准输出上跟随一个换行符。
在其他实现的文档中也可以找到类似的语句。例如echo
从coreutils
,您可能会在 GNU/Linux 上找到:
echo
将每个给定字符串写入标准输出,每个字符串之间有一个空格,最后一个字符串后面有一个换行符。
如果您确实想echo
在单独的行上打印文件名,则必须将它们作为单个字符串提供:
$ touch "small1.jpg" "small2.jpg" "small photo 1.jpg" "small photo 2.jpg"
$ (set -- small*.jpg; IFS='
'; echo "$*")
small1.jpg
small2.jpg
small photo 1.jpg
small photo 2.jpg
在这里,我们利用特殊参数的行为*
:在双引号内它扩展为一个字其中位置参数数组的元素使用IFS
变量的第一个字符(我们将其设置为换行符)连接起来。
该(...)
语法用于在子 shell 环境中执行命令——我们通常不想影响主 shell。
但请注意,所有echo
的限制仍然适用,如中所述史蒂芬的回答,因此不建议在这种情况下使用它。