Home > Software engineering >  Filename does not contain on macbook zsh
Filename does not contain on macbook zsh

Time:11-19

On macbook I'm trying to compile all proto files in a folder that do not contain the word server. Zsh and bash seem to be working a bit different than on linux. My coworker could get it wo work by using

[^_server]

in the path on linux. But that does not seem to work on mac. I managed to get this

protoc --dart_out=grpc:proto/ ./api/(core|editor|google)/**/*(_server).proto --proto_path=./api

which compiles all the proto files containing _server in the filename in the folders core, editor and google. But I need it to be all files that don't contain _server in the name in the folders core, editor and google.

CodePudding user response:

Try this:

setopt extendedglob
protoc --dart_out=grpc:proto/ \
  ./api/(core|editor|google)/**/(^*_server).proto \
  --proto_path=./api

The demonstrations of the glob patterns below use this directory tree:

api/
├── core/
│   ├── core_notserver.proto
│   ├── core_server.proto
│   ├── core_server.txt
│   └── coresub/
│       ├── coresub_notserver.proto
│       └── coresub_server.proto
├── editor/
│   ├── ed_notserver.proto
│   └── ed_server.proto
├── google/
│   ├── ends with excluded letter e.proto
│   ├── ends with included letter a.proto
│   ├── gl_server.proto
│   └── gl_server.txt
└── other/
    ├── other_notserver.proto
    └── other_server.proto

With _server in the filename:

> print -l ./api/(core|editor|google)/**/*_server.proto
./api/core/core_server.proto
./api/core/coresub/coresub_server.proto
./api/editor/ed_server.proto
./api/google/gl_server.proto

Without _server in the filename.
There are two ways to do a pattern negation with zsh - they both require enabling extended glob patterns, with setopt extendedglob. The option just needs to be set once, e.g. in ~/.zshrc:

> setopt extendedglob
> print -l ./api/(core|editor|google)/**/(*~*_server).proto
./api/core/core_notserver.proto
./api/core/coresub/coresub_notserver.proto
./api/editor/ed_notserver.proto
./api/google/ends with excluded letter e.proto
./api/google/ends with included letter a.proto

> print -l ./api/(core|editor|google)/**/(^*_server).proto
./api/core/core_notserver.proto
./api/core/coresub/coresub_notserver.proto
./api/editor/ed_notserver.proto
./api/google/ends with excluded letter e.proto
./api/google/ends with included letter a.proto

The pattern [^_server] will not give the results you're looking for. With square braces, the values are used as individual characters to include, or with ^ exclude, from the results. It is not treated as the sequence _server. Your coworker may have had a set of filenames that gave the appearance of working properly.

Here, any filename with a base part that ends with _, s, e, r, or v will be excluded from the glob results:

> print -l ./api/(core|editor|google)/**/*[^_server].proto
./api/google/ends with included letter a.proto

More info on globbing here.

  • Related