如何在 Linux 的 Bash Shell 中使用大括号扩展

大括号扩展是一种有用的技术,可以生成可在脚本和别名以及 Linux 命令行中使用的字符串列表。通过减少输入来节省时间并避免错误。
大括号扩展
在 Bash shell 执行终端窗口中的命令或脚本中的行之前,它会检查是否需要对命令执行任何替换。变量名被它们的值替换,别名被它们的简写命令替换,并且执行任何扩展。大括号扩展是 Bash 支持的一种扩展形式。
大括号扩展在现代 shell 中可用,但它可能在某些旧 shell 中缺失。如果您要在脚本中使用大括号扩展,请确保调用支持大括号扩展的 shell,例如 Bash:
#!/bin/bash
我们将使用 Bash 作为示例。
生成字符串列表可能看起来更像是一种新奇而不是好处,但它确实提供了一些可以节省时间和击键次数的功能。通常,它可以为问题或需求提供简单而优雅的解决方案。
简单扩展
大括号展开包含在一对大括号“{}”之间。它可以是逗号分隔项的列表或范围说明符。除非您将字符串用引号“\
”括起来,否则大括号内不允许有空格。”
对于以逗号分隔的列表,扩展过程依次获取每个元素并将其传递给调用命令。在此示例中,echo
只是将它们打印在终端窗口中。请注意,逗号将被忽略。
echo {one,two,three,four}
列表可以是单词或数字。
echo {1,2,3,4}
列表元素的顺序是完全任意的。
echo (4,2,3,1)

扩展范围有一个开始和结束字符,由两个句点“..
”连接,没有任何空格。扩展会自动提供所有缺少的列表元素,以便创建从开始字符到结束字符的整个范围。
这将打印从 1 到 10 的数字。
echo {1..10}

编号是任意的。它不必从一个开始。
echo {3..12}

可以指定范围,以便它们向后运行。这将生成一个从五到一的列表。
echo {5..1}

范围可以包括负数。
echo {4..-4}

正如我们之前指出的,范围具有开始和结束字符。它不一定是数字。它可以是一封信。
echo {q..v}
字母也可以向后运行。
echo {f..a}

在循环中使用大括号扩展
您可以在脚本的循环中使用带范围的大括号扩展。
for i in {3..7}
do
echo $i
done
大括号扩展范围让您可以使用字符作为循环变量。
for i in {m..q}
do
echo $i
done
循环通常用在脚本中,但没有什么可以阻止您将它们输入命令行以查看会发生什么。
for i in {3..7}; do echo $i; done

for i in {m..q}; do echo $i; done

连接和嵌套
两个相邻的扩展不会一个接一个地独立运行。它们互操作。第一个扩展中的每个元素都由第二个扩展中的每个元素作用。
echo {q..v}{1..3}

扩展也可以嵌套。嵌套扩展将作用于它之前的元素。
echo {part-1,part-2{a,b,c,d},part-3}

您还可以通过创建以逗号分隔的范围扩展列表来嵌套扩展。
echo {{5..0},{1..5}}

序言和后记
您可以在大括号扩展之前和之后放置文本,以使该文本包含在扩展结果中。放在扩展前面的文本称为序言,而放在大括号扩展后面的文本称为后记。
此命令使用前导码。
echo chapter{1..3}

这个例子使用了一个后记:
echo {contents,paper,bilbiography}.md

而这个命令同时使用了两者。
echo chapter-{1..4}.md

扩展文件名和目录
正如您现在可能已经猜到的那样,大括号扩展的主要用途之一是创建可以传递给其他命令的文件和目录名称。我们一直在使用 echo
作为一种方便的方式来查看触发扩展时究竟发生了什么。您可以替换任何将文件名或目录名作为输入并使用大括号扩展的命令。
要快速创建一些文件,请使用 touch
:
touch file-{1..4}.txt
ls *.txt

如果您有许多基本名称相同但文件扩展名不同的文件,并且您想要对其中的一个子集执行操作,大括号扩展可以提供帮助。在这里,我们将以“program”为基本名称的文件子集压缩到名为“source-code.zip”的 ZIP 文件中。
开发目录包含许多文件,这些文件将与您的主程序具有相同的基本名称。通常,您不想备份或分发“.o”目标文件之类的文件。这是一种只包含感兴趣的文件类型的巧妙方法。
zip source-code program{.c,.h,.css}

此命令将制作一个文件的副本并向其附加“.bak”,从而制作原始文件的备份副本。值得注意的一点是,大括号扩展包含一个逗号分隔的列表,但第一个元素是空的。如果我们没有包含逗号,就不会发生扩展。
cp brace/new/prog-1.c{,.bak}
ls brace/new/prog-1.c.bak

要对不同目录中的两个文件执行某些操作,我们可以在文件路径中使用大括号扩展。
在此示例中,“brace”目录包含两个子目录,一个名为“new”,一个名为“old”。它们包含同一组源代码文件的不同版本。我们将使用 diff
程序来查看“prog-1.c”的两个版本之间的差异。
diff brace/{new,old}/prog-1.c

如果您有需要在项目开始时创建的标准目录框架,则可以使用大括号扩展快速创建它们。 mkdir
-p
(父)选项会在创建子目录时创建任何缺失的父目录。
mkdir -p {source,build,man,help{/pages,/yelp,/images}}
tree

您可以在 wget
中使用大括号扩展来下载多个文件。
在此命令中,我们将从名为“test1”和“test2”的两个目录下载文件。每个目录包含两个名为“picture1”和“picture2”的文件。
wget https://www.URL-of-your-choice.com/test{1,2}/picture{001,002}.jpg

列出文件会向您显示检索到的文件以及 wget
如何重命名文件以避免与现有文件发生名称冲突。
ls picture*.*

拥抱大括号
试一试,它可能会进入您的命令行入门技巧集。