如何在 shell (bash) 中使用大括号
How to use curly braces in a shell (bash)
我目前正在尝试重现基本的 shell 行为,更具体地说是 globbing 行为。
我正在测试其中带有花括号的命令,发现了这种我不理解的行为。
首先,我正在工作的目录的内容如下:
1abc 2abc 3abc abc1 abc2 abc3
然后,我输入了以下命令:ls {[1-3],[a-c]}*
,它return按预期为我编辑了上面的所有文件。
最后,我尝试了这个命令:ls {{,[1-3]},[a-c]}*
,如您所见,它有重叠的花括号。现在我不明白的是这个命令的 return,因为它给了我这个:1abc 1abc 2abc 2abc 3abc 3abc abc1 abc1 abc2 abc2 abc3 abc3
如您所见,所有文件都 return 编辑了两次,我不知道 shell 是如何解释的。
我希望我的解释很清楚。
Bash 展开
{{,[1-3]},[a-c]}*
第一步(大括号扩展)到
* [1-3]* [a-c]*
在第二步(通配)bash 将 *
扩展到所有文件 和 [1-3]*
到所有以 [=14= 开头的文件],2
或 3
和 将 [a-c]*
扩展到所有以 a
、b
或 [=20 开头的文件=].
字符串 {{,[1-3]},[a-c]}*
是一个解释为 brace expansion 的表达式,由以下模式组成:
- "emptiness" (
{,
),
[1-3]
,以及
[a-c]
.
*
字符(意思是 "every filename in the given directory")应用于它们中的每一个:
* => 1abc 2abc 3abc abc1 abc2 abc3
[1-3]* => 1abc 2abc 3abc
[a-c]* => abc1 abc2 abc3
嵌套表达式的事实并没有改变它的含义,即只是三个模式的列表。使用更简单的表达式(如 {,[1-3],[a-c]}*
或另一个 "list of lists"(如 {,{[1-3],[a-c]}}*
.
)可以实现相同的效果
如果将表达式传递给 echo
,它将打印上面各行中的所有字符,一个接一个:
$ echo {{,[1-3]},[a-c]}*
1abc 2abc 3abc abc1 abc2 abc3 1abc 2abc 3abc abc1 abc2 abc3
但 ls
默认按字母顺序对条目进行排序:
$ ls {{,[1-3]},[a-c]}*
1abc 1abc 2abc 2abc 3abc 3abc abc1 abc1 abc2 abc2 abc3 abc3
我目前正在尝试重现基本的 shell 行为,更具体地说是 globbing 行为。 我正在测试其中带有花括号的命令,发现了这种我不理解的行为。 首先,我正在工作的目录的内容如下:
1abc 2abc 3abc abc1 abc2 abc3
然后,我输入了以下命令:ls {[1-3],[a-c]}*
,它return按预期为我编辑了上面的所有文件。
最后,我尝试了这个命令:ls {{,[1-3]},[a-c]}*
,如您所见,它有重叠的花括号。现在我不明白的是这个命令的 return,因为它给了我这个:1abc 1abc 2abc 2abc 3abc 3abc abc1 abc1 abc2 abc2 abc3 abc3
如您所见,所有文件都 return 编辑了两次,我不知道 shell 是如何解释的。
我希望我的解释很清楚。
Bash 展开
{{,[1-3]},[a-c]}*
第一步(大括号扩展)到
* [1-3]* [a-c]*
在第二步(通配)bash 将 *
扩展到所有文件 和 [1-3]*
到所有以 [=14= 开头的文件],2
或 3
和 将 [a-c]*
扩展到所有以 a
、b
或 [=20 开头的文件=].
字符串 {{,[1-3]},[a-c]}*
是一个解释为 brace expansion 的表达式,由以下模式组成:
- "emptiness" (
{,
), [1-3]
,以及[a-c]
.
*
字符(意思是 "every filename in the given directory")应用于它们中的每一个:
* => 1abc 2abc 3abc abc1 abc2 abc3
[1-3]* => 1abc 2abc 3abc
[a-c]* => abc1 abc2 abc3
嵌套表达式的事实并没有改变它的含义,即只是三个模式的列表。使用更简单的表达式(如 {,[1-3],[a-c]}*
或另一个 "list of lists"(如 {,{[1-3],[a-c]}}*
.
如果将表达式传递给 echo
,它将打印上面各行中的所有字符,一个接一个:
$ echo {{,[1-3]},[a-c]}*
1abc 2abc 3abc abc1 abc2 abc3 1abc 2abc 3abc abc1 abc2 abc3
但 ls
默认按字母顺序对条目进行排序:
$ ls {{,[1-3]},[a-c]}*
1abc 1abc 2abc 2abc 3abc 3abc abc1 abc1 abc2 abc2 abc3 abc3