shelljs / shx

Portable Shell Commands for Node
MIT License
1.72k stars 44 forks source link

lower case "ls" with mixed case fails with internal caps #162

Closed backspaces closed 5 years ago

backspaces commented 5 years ago

TLDR: I want to list only the files that are all lower case .js files via:

shx ls '[a-z]*.js'

This works fine for skipping files that start with a Capital letter (TitleCase), but not with files with an internal Capital letter (camelCase).

Details: The contents of the dir initially looks like:

AntsModel.js            TSPModel.js             flock.js
ButtonsModel.js         WalkersModel.js         hello.js
DiffuseModel.js         WallFollowerModel.js    index.html
DropletsModel.js        WaterModel.js           linktravel.js
ExitModel.js            ants.js                 roads.js
FireModel.js            buttons.js              roads14vt.json
FlockModel.js           diffuse.js              tsp.js
HelloModel.js           droplets.js             walkers.js
LinkTravelModel.js      exit.js                 wallfollower.js
RoadsModel.js           fire.js                 water.js

And shx ls '[a-z]*.js' works as expected:

ants.js
buttons.js
diffuse.js
droplets.js
exit.js
fire.js
flock.js
hello.js
linktravel.js
roads.js
tsp.js
walkers.js
wallfollower.js
water.js

But if we now add a camelCase file: touch fooBar.js, the above ls includes it: shx ls '[a-z]*.js'

ants.js
buttons.js
diffuse.js
droplets.js
exit.js
fire.js
flock.js
fooBar.js   <<<
hello.js
linktravel.js
roads.js
tsp.js
walkers.js
wallfollower.js
water.js

I'm using this on a mac, latest Mojave, whose file system is case insensitive, but I don't think that is the problem.

Thanks! And what a great project!

nfischer commented 5 years ago

I think this is WAI. shx ls '[a-z]*.js' means "list all files which start with a lower-case letter, are followed with zero or more characters, and end with '.js'." This seems to be the behavior you're seeing.

Note: shx ls does not support regex, it supports glob patterns. So * means "zero or more of anything" rather than "zero or more of the previous expression." It seems like you could solve this with the *(a|b|c) pattern listed on the glob page though (I haven't tried).

Thanks! And what a great project!

Glad you appreciate it!

backspaces commented 5 years ago

Very clear, thanks.

backspaces commented 5 years ago

Note: here's a solution for finding just the all-lower case filenames: grep('-v', '[A-Z]')