如何在Bash中编写奇特的多线括号扩展?

Ame*_*hel 3 bash indentation curly-braces brace-expansion

我正在处理这样一条线:

mkdir -p "$DEST_ROOT_PATH/"{"$DEST_DIR1","$DEST_DIR2", ..., "$DEST_DIRN"}
Run Code Online (Sandbox Code Playgroud)

这条线很长.我想剪切它,使其宽度适合80列线.我试图用反斜杠逃避结束,但空间对齐打破了扩展:

$ echo "ha"{a,b,\
>           c}
ha{a,b, c}
Run Code Online (Sandbox Code Playgroud)

123*_*123 7

你可以使用这个恶心的黑客.

echo "ha"{a,b,\
> `      `c}
Run Code Online (Sandbox Code Playgroud)

它打开一个没有任何内容的子shell,但在扩展之前进行处理,因此扩展只看到一个空的空间

  • 这可能很恶心,但它很聪明! (3认同)

fed*_*qui 6

这是正常的行为.从Bash参考手册:

3.5.1支撑扩张

支撑扩展是一种可以生成任意字符串的机制.此机制类似于文件名扩展(请参阅文件名扩展),但生成的文件名不需要存在. 要扩展的模式采用可选前导码的形式,后跟一系列逗号分隔的字符串或一对大括号之间的序列表达式,后跟可选的postscript.前导码以大括号内包含的每个字符串为前缀,然后将postscript附加到每个结果字符串,从左向右扩展.

支撑扩展不允许放置\在下一行中的元素和下一行中的下一个元素之间的空格.

为什么?因为它在处理时被删除:

3.1.2.1逃逸角色

一个未引用的反斜杠'\'是Bash转义字符.它保留了下一个字符的字面值,但换行除外.如果出现\newline对,并且未引用反斜杠本身,则\newline将被视为行继续(即,它将从输入流中删除并被有效忽略).

所以当你说

something + \ + <new line> + another_thing
Run Code Online (Sandbox Code Playgroud)

Bash将其转换为

something + another_thing
Run Code Online (Sandbox Code Playgroud)

那你能做什么?

添加反斜杠,然后从下一行的开头开始编写:

mkdir -p "$DEST_ROOT_PATH/"{"$DEST_DIR1",\
"$DEST_DIR2",\
...,\
"$DEST_DIRN"}
Run Code Online (Sandbox Code Playgroud)

一些例子

当你说:

$ echo "ha"{a,b\
>    c}
ha{a,b c}
Run Code Online (Sandbox Code Playgroud)

然后向上移动箭头你会看到这是执行的命令:

$ echo "ha"{a,b   c}
Run Code Online (Sandbox Code Playgroud)

所以只说:

$ echo "ha"{a,b\
> c}
haa habc
Run Code Online (Sandbox Code Playgroud)

向上移动时你会看到这个:

$ echo "ha"{a,b,c}
Run Code Online (Sandbox Code Playgroud)

另一个例子:

$ cat touch_files.sh
touch X{1,\
2,3}
$ bash touch_files.sh
$ ls X*
X1 X2 X3
Run Code Online (Sandbox Code Playgroud)

  • 我想他们已经知道了.`但空间对齐打破了扩张:` (2认同)