12

我得到:

$ echo -e "D"{a,b,c}".jpg\n"
Da.jpg
 Db.jpg
 Dc.jpg

注意:输出的第 2 行和第 3 行 Db 和 Dc 之前的多余空格。

为什么会有这些?

谢谢,丹

编辑:由于我的实际目标中有空格(我本来应该写的):

echo -e "Name"{,.}" "{-,}"extra"{,so}" 5v5 "{one,two,No\ four}{,!,\!\!}"\n"

这里的大多数解决方案都不适合我(for loop、xarg、tr)。Printf 没有工作,因为我想使用多个大括号扩展来制作粤语产品。

我结合了 3 个解决方案(mletterle 的 \b、Dennis Williamson 的额外空间和 Jim Dennis 使用更少的引号)来获得:

echo -e "" \\bName{,.}\ {-,}extra{,so}\ 5v5\ {one,two,No\ four}{,\!,\!\!}\\n

感谢所有回答的人!我从你的回复中学到了很多!

4

7 回答 7

12

因为这就是大括号扩展的作用。来自man bash,在标题下Brace expansion

要大括号扩展的模式采用可选前导码的形式,后跟......一系列逗号分隔的字符串......然后是可选的后记。序言作为前缀添加到大括号中包含的每个字符串,然后将后记附加到每个结果字符串,从左到右扩展 例如,a{d,c,b}e 扩展为 'ade ace abe'</p>

所以在你的例子中,“D”是序言,“.jpg\n”是后记。

因此,在发生大括号扩展后,您将得到:

echo -e Da.jpg\n Db.jpg\n Dc.jpg\n

正如 hewgill指出的那样,shell 然后将其拆分为三个标记并将它们传递给 echo;它输出由空格分隔的每个标记。要获得所需的输出,您需要使用此处的众多建议之一,不要在令牌之间重新插入不需要的空间。

它更长,可能不是最好的方法,但以下给出了您所追求的输出:

for file in "D"{a,b,c}".jpg"
do
  echo ${file}
done
于 2010-01-05T01:23:21.070 回答
12

使用更便携的 printf

$ printf "D%s.jpg\n" {a,b,c}
Da.jpg
Db.jpg
Dc.jpg
于 2010-01-05T01:54:30.197 回答
5

echo总是在参数之间添加空格。在没有的情况下尝试您的命令\n并比较结果。

于 2010-01-05T01:22:46.920 回答
2

您可以通过在前面添加 null 来获得更一致的外观:

$ echo -en "" "D"{a..c}".jpg\n"
 Da.jpg
 Db.jpg
 Dc.jpg

现在他们都有一个额外的空间。此外, using-n消除了最后的额外换行符。此外,您可以在大括号扩展中使用范围。

于 2010-01-05T02:46:41.903 回答
2

最简单和最干净的解决方案是在每行的前面添加一个退格键:

echo -e -n "\bD"{a,b,c}".jpg\n"

这会产生所需的输出。

于 2010-01-05T01:53:20.107 回答
2

您可以通过使用 xargs 将第一个 echo 吐出的参数分隔成一行来获得所需的效果:

$ echo "D"{a,b,c}".jpg" | xargs -n1 echo
Da.jpg
Db.jpg
Dc.jpg
于 2010-01-05T01:42:40.190 回答
0

这是一个使用sed(基于https://stackoverflow.com/a/2003856/8180143)的解决方案:

$ echo -en "" "D"{a..c}".jpg\n" | sed 's/ //'
Da.jpg
Db.jpg
Dc.jpg

此解决方案的优点是使用具有空格的输入,例如,

$ echo -en "" "D "{a..c}".jpg\n" | sed 's/ //'
D a.jpg
D b.jpg
D c.jpg
于 2019-02-08T20:32:40.610 回答