7

When using the tree command, I'd like to exclude listing *.png and *.svg from the output. The problem is that every bracket expansion I try doesn't work. Is it because of how tree processes commandline arguments?

tree -I *.{svg,png}
tree -I '*.{svg,png}'
tree -I '{*.svg,*.png}'
tree -I '{*.svg,*.png}'
tree -I '*.{p,s}(v,n}g'
tree -I '*.{svg|png}'

Specs:

  • GNU bash, version 4.4.23
  • tree v1.7.0
Attie
  • 20,734

1 Answers1

12

-I is the inverse of -P... the manual gives more information on what is acceptable for the latter:

https://linux.die.net/man/1/tree

-P pattern

List only those files that match the wild-card pattern.

Note: you must use the -a option to also consider those files beginning with a dot . for matching.

Valid wildcard operators are * (any zero or more characters), ? (any single character), [...] (any single character listed between brackets (optional - (dash) for character range may be used: ex: [A-Z]), and [^...] (any single character not listed in brackets) and | separates alternate patterns.

There's no mention of the shell's brace expansion syntax of {a,b}... This expansion is handled by tree, not bash.

And unfortunately you can't specify -I multiple times...

Instead you need to list the full patterns with a pipe (|) to separate them:

tree -I '*.svg|*.png'

Note the use of single quotes to prevent the shell from expanding the asterisk (*) or variables (introduced by a dollar - $).


Note also that it's not even possible to coerce the shell's brace expansion, as shown below:

$ tree -I '*.'{svg,png}
+ tree -I '*.svg' '*.png'
*.png [error opening dir]
Attie
  • 20,734