使用 xonsh 进行列表理解

List comprehension with xonsh

我对此还是个新手,但是否可以使用列表理解语法在 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

我已经差不多了,有必要进一步包装命令:

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

原因如下:

  • 鉴于顶层命令是list-comprehension,我们输入Python-mode
  • 我们想执行一个bash命令(touch)所以我们需要进入子进程模式 $(
  • 但是,该命令的参数需要使用 Python 进行字符串插值,因此编写命令本身需要 Python-mode,因此 @(

看起来您找到了执行此操作的方法 -- 有时特定子进程命令的行为会影响您将它们组合在一起的方式。

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

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

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

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

说明嵌套的必要性$[ .. @(:

  • 顶级命令是列表理解,所以我们从Python-模式开始;
  • 我们想要执行一个bash命令(touch)所以我们需要使用$[(或$(来捕获输出)进入子进程模式;
  • 但是该命令的参数需要使用 Python 进行字符串插值,因此 Python-mode 再次使用 @(