使用 echo 每行打印一个文件

使用 echo 每行打印一个文件

如何使用 打印每行一个文件/目录列表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 实现复制:printprintfzsh

print -f '%s\n' -- small*jpg

请注意,如果没有给出任何参数,所有这些函数仍会打印一个空行。更好的方法println是将其写成如下函数:

println() {
  [ "$#" -eq 0 ] || printf '%s\n' "$@"
}

zsh

println() print -rC1 -- "$@"

答案2

echo仅使用空格来分隔作为参数接收的字符串。

由于您的问题已被标记,这里是说help echobash(强调我的):

显示 ARG,由单个空格字符分隔然后在标准输出上跟随一个换行符。

在其他实现的文档中也可以找到类似的语句。例如echocoreutils,您可能会在 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的限制仍然适用,如中所述史蒂芬的回答,因此不建议在这种情况下使用它。

相关内容