6

I want to use xonsh to bzip several files in a directory. I first attempt this with the following:

$ ls
table_aa.csv    table_amgn.csv  table_csco.csv  table_esrx.csv  table_hal.csv  table_jbl.csv  table_pcg.csv   table_zmh.csv
table_aapl.csv  table_amzn.csv  table_d.csv     table_gas.csv   table_hp.csv   table_jpm.csv  table_usb.csv
$ for fn in ls:
..    bzip2 fn
..
NameError: name 'ls' is not defined

OK, so I use $() explicitly

$ for fn in $(ls).split():
.     bzip2 fn
bzip2: Can't open input file fn: No such file or directory.
bzip2: Can't open input file fn: No such file or directory.

Is there a better way to do this?

$ xonsh --version
('xonsh/0.3.4',)
MRocklin
  • 55,641
  • 23
  • 163
  • 235

2 Answers2

9

You are very close with the second example. The only thing to note is that fn is a Python variable name, so you have to use @() to pass it to a subprocess:

$ for fn in $(ls).split(): . bzip2 @(fn)

Also, on v0.3.4, you could use regex globbing instead of ls,

$ for fn in `.*`: . bzip2 @(fn)

And at least on master, you can now iterate through !() line-by-line, which means that the following will also work if you are wedded to ls:

$ for fn in !(ls): . bzip2 @(fn)

Anthony Scopatz
  • 3,265
  • 2
  • 15
  • 14
2

Using ls:

for fn in !(ls):
    print(fn.rstrip())

Using globs (available in regex, shell, and path varieties):

for fn in g`*`:
    print(fn)

Using Python APIs (see the os, glob, or pathlib modules):

import os
for fn in os.listdir():
    print(fn)
AstraLuma
  • 609
  • 5
  • 16
  • the reminder to just use Python is really helpful. It's hard to get out of the shell mindset when you're used to being stuck in it. I've decided to `import os` inside my .xonshrc so that it's already available whenever I want to use it. – Peter Gaultney Oct 23 '22 at 00:18