3

我对此仍然很陌生,但是是否可以xonsh使用列表理解语法执行多个命令?

我希望以下内容会创建五个文件file00file04但它会出错:

$ [@(['touch', 'file%02d' % i]) for i in range(5)]
............................ 
xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
  File "<string>", line None
SyntaxError: <xonsh-code>:1:1: ('code: @(',)
[@(['touch', 'file%02d' % i]) for i in range(5)]
 ^

我希望这可以工作,因为以下工作正常:

$ [i for i in range(5)]
[0, 1, 2, 3, 4]

$ @(['touch', 'file%02d' % 3])
$ ls
file03
4

3 回答 3

2

看起来您找到了一种方法来做到这一点——有时特定子进程命令的行为会影响您将它们组合在一起的方式。

在 的情况下touch,由于它可以接受多个参数,因此将其包装在列表理解中(我能想到的)的最直接方法是

touch @([f'file_{i}' for i in range(5)])

于 2018-05-18T16:50:02.760 回答
2

最接近原始代码的方法是使用子进程:

[$[touch @('file%02d' % i)] for i in range(5)]

解释嵌套的需要$[ .. @(

  • 顶层命令是一个列表理解,所以我们从 Python 模式开始;
  • 我们想要执行一个 bash 命令 ( touch) 所以我们需要进入 subprocess-mode $[(或$(捕获输出);
  • 但是该命令的参数需要使用 Python 进行字符串插值,因此 Python 模式再次使用@(.
于 2018-05-19T14:18:34.517 回答
1

我快到了,有必要进一步包装命令:

$ [ $(@(['touch', 'file%02d' % i])) for i in range(5)]

原因如下:

  • 鉴于顶级命令是列表理解,我们进入 Python 模式
  • 我们想要执行一个 bash 命令 ( touch) 所以我们需要进入 subprocess-mode$(
  • 但是,该命令的参数需要使用 Python 进行字符串插值,因此编写命令本身需要 Python 模式,因此@(
于 2018-05-18T15:38:38.343 回答