如何使用bash括号扩展输出逗号分隔的字符串


17

我想要

$ echo a{b,c,d}

输出以逗号分隔的列表,例如

ab,ac,ad

而不是通常的输出

ab ac ad

在命令行上最简单的方法是什么?

Answers:


9

假设元素不包含空格,则可以将空格转换为逗号:

echo a{b,c,d} | tr ' ' ,

产生:

ab,ac,ad

您还可以将范围与字符一起使用:

echo a{b..d} | tr ' ' ,

如果您想要更大的范围,这尤其有用。


13

看来bash不使用$ IFS来加入生成的单词。另一种技术是将生成的单词存储在数组中,然后$ IFS 起作用:

我将使用一个子外壳,所以我不会更改该外壳的IFS:选择其中一个

( words=( a{b,c,d} ); IFS=,; echo "${words[*]}" )
( set -- a{b,c,d}; IFS=,; echo "$*" )

这会将逗号分隔的字符串发送到stdout。如果要捕获它:

joined=$( set -- a{b,c,d}; IFS=,; echo "$*" )

它根本加入生成的单词。这就是重点,它扩展为单独的单词。
斯特凡Chazelas


2

像显示的那样展开元素,然后对其进行循环,将逗号添加到除第一次迭代之外的所有迭代中:

for i in a{b,c,d}; do
  u="${u:+$u, }$i"
done
echo "$u"

结果:

ab, ac, ad

请参见bash参数替换


1

这是仅适用于bash的解决方案。

(IN=$(echo a{b,c,d}); echo ${IN// /,})
# ab,ac,ad

分号之前的部分分配ab ac ad给变量IN,第二部分使用搜索和替换将所有空格更改为逗号。将//意味着所有的比赛,不只是第一个。

在子外壳程序(包含括号)中完成所有操作,以免污染您的名称空间。


1

值得注意的是,在许多情况下,在这样的列表中可以使用逗号结尾。 如果结尾的逗号是可接受的,则处理替换的最简单方法是printf

some-command "$(printf %s, a{b,c,d} )"

some-command这是在逗号分隔的列表上运行的命令,它不关心尾随的逗号。)

实际上,即使您不必使用逗号结尾,也可以使用printf; 您只需要指定期望的参数数量,这会使很长的列表变得笨拙:

some-command "$(printf %s,%s,%s a{b,c,d} )"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.