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.