Понимание списка с помощью xonsh

Я все еще новичок в этом, но возможно ли выполнить несколько команд в xonsh используя синтаксис списка-понимания?

Я ожидал бы следующее, чтобы создать пять файлов file00 в file04, но это ошибки вместо:

$ [@(['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

3 ответа

Решение

Наиболее близким к вашему исходному коду является использование подпроцесса:

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

Чтобы объяснить необходимость вложения $[ .. @(:

  • Команда верхнего уровня является списком, поэтому мы начинаем в режиме Python;
  • Мы хотим выполнить команду bash (touch) поэтому нам нужно войти в подпроцесс-режим с $[ (или же $( захватить вывод);
  • Но аргумент этой команды требует интерполяции строк с Python, следовательно, режим Python снова с @(,

Похоже, вы нашли способ сделать это - иногда поведение конкретной команды подпроцесса может влиять на то, как вы все это соберете.

В случае touch, поскольку он может принимать несколько аргументов, самый простой способ обернуть это в понимание списка (о котором я могу думать) - это сделать

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

Я был почти там, нужно обернуть команду дальше:

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

Причина этого заключается в следующем:

  • Учитывая, что команда верхнего уровня является списком, мы входим в режим Python
  • Мы хотим выполнить команду bash (touch) поэтому нам нужно войти в подпроцесс-режим с $(
  • Однако аргумент этой команды требует интерполяции строк с Python, поэтому для написания самой команды требуется режим Python, следовательно @(
Другие вопросы по тегам