3

我正在处理这样的一行:

mkdir -p "$DEST_ROOT_PATH/"{"$DEST_DIR1","$DEST_DIR2", ..., "$DEST_DIRN"}

这条线很长。我想切割它,使其宽度适合 80 列线。我试图用反斜杠转义行尾,但空间对齐会破坏扩展:

$ echo "ha"{a,b,\
>           c}
ha{a,b, c}
4

4 回答 4

7

你可以使用这个令人作呕的黑客。

echo "ha"{a,b,\
> `      `c}

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

于 2016-06-14T14:29:33.987 回答
6

这是正常行为。来自 Bash 参考手册:

3.5.1 大括号展开

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

大括号扩展不允许放置\在下一行和下一个元素之间的元素之间存在空格。

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

3.1.2.1 转义字符

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

所以当你说

something + \ + <new line> + another_thing

Bash 将其转换为

something + another_thing

那你能做什么?

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

mkdir -p "$DEST_ROOT_PATH/"{"$DEST_DIR1",\
"$DEST_DIR2",\
...,\
"$DEST_DIRN"}

一些例子

当你说:

$ echo "ha"{a,b\
>    c}
ha{a,b c}

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

$ echo "ha"{a,b   c}

所以只说:

$ echo "ha"{a,b\
> c}
haa habc

向上移动时您会看到:

$ echo "ha"{a,b,c}

另一个例子:

$ cat touch_files.sh
touch X{1,\
2,3}
$ bash touch_files.sh
$ ls X*
X1 X2 X3
于 2016-06-14T14:27:30.623 回答
2

因此我接受了@123 的回答,这是我选择的:

mkdir -p "$DEST_ROOT_PATH/"{"$DEST_DIR1","$DEST_DIR2"}
mkdir -p "$DEST_ROOT_PATH/"{"$DEST_DIR3","$DEST_DIR4"}

这里没有很多目标目录,所以我认为它在花哨和令人作呕的黑客和破坏缩进的令人沮丧的反斜杠之间取得了很好的平衡。

于 2016-06-14T14:57:13.017 回答
1

我会这样做(尽管它只解决了您创建多个目录的特定任务并且没有回答标题中所述的问题):

for d in \
      "$DEST_DIR1" \
      "$DEST_DIR2" \
       ...         \
      "$DEST_DIRn" \
      ;
do
    mkdir -p "$DEST_ROOT_PATH/$d"
done

这种方法的优点是维护列表更容易一些。

一般来说,当您注意到语法糖开始造成不便时,您应该停止使用语法糖。

于 2016-06-17T09:06:38.013 回答