I'm learning xonsh. I tried the following simple script, but it fails at zipinfo -1 $mzip_str
, specifically at expanding mzip_str
.
#!/usr/bin/env xonsh
from pathlib import Path
my_path = Path('/path/to/downloads/')
dir_list = my_path.glob('*.zip')
for my_zip in dir_list:
mzip_str = str(my_zip)
zip_dir_names = $(zipinfo -1 $mzip_str | grep -E '.*/$')
print(zip_dir_names)
In the xonsh shell, I get these results:
➤ zip_dir_names = $(zipinfo -1 mzip_str)
zipinfo: cannot find or open mzip_str, mzip_str.zip or mzip_str.ZIP.
➤ zip_dir_names = $(zipinfo -1 $mzip_str)
zipinfo: cannot find or open $mzip_str, $mzip_str.zip or $mzip_str.ZIP.
➤ zip_dir_names = $(zipinfo -1 @mzip_str)
zipinfo: cannot find or open @mzip_str, @mzip_str.zip or @mzip_str.ZIP.
➤ zip_dir_names = $(zipinfo -1 !mzip_str)
zipinfo: cannot find or open mzip_str, mzip_str.zip or mzip_str.ZIP.
From the official tutorial
The
@(<expr>)
operator form works in subprocess mode, and will evaluate arbitrary Python code. The result is appended to the subprocess command list. If the result is a string or bytes, it is appended to the argument list. If the result is a list or other non-string sequence, the contents are converted to strings and appended to the argument list in order. If the result in the first position is a function, it is treated as an alias (see the section on Aliases below), even if it was not explicitly added to thealiases
mapping. Otherwise, the result is automatically converted to a string.
So the relevant line should look like (Untested as I don't have this xonsh
installed):
zip_dir_names = $(zipinfo -1 @(my_zip) | grep -E '.*/$')
But it sounds like $()
returns a string and you probably want zip_dir_names
to be a list if you want to do anything with it but print it. Something like
zip_dir_names = [ name for name in !(zipinfo -1 @(my_zip)) if name.endsWith("/") ]
might work better. Or just use the standard Python zipfile module module instead of an external program, of course.
zip_dir_names = [ f.filename for f in ZipFile(my_zip).infolist() if f.is_dir() ]