Someone mentioned on stackoverflow in the trees
man page that this is why the -P
switch doesn't exclude things that don't match the pattern.
BUGS
Tree does not prune "empty" directories when the -P and -I options are
used. Tree prints directories as it comes to them, so cannot accumu‐
late information on files and directories beneath the directory it is
printing.
So it doesn't appear to be possible to get tree
to filter its output using the -P switch.
EDIT #1
From a question I had posted on SO that got closed. Someone, @fhauri, had posted the following information as alternative ways to accomplish what I was trying to do with the tree
command. I'm adding them to my answer here for completeness.
-d
switch ask to not print files:
-d List directories only.
So if you WANT use this, you could:
tree tstdir -P '*qm*' -L 1 | grep -B1 -- '-- .*qm'
|-- id1
| `-- aqm_P1800-id1.0200.bin
--
|-- id165
| `-- aqm_P1800-id165.0200.bin
|-- id166
| `-- aqm_P1800-id166.0200.bin
--
|-- id17
| `-- aqm_P1800-id17.0200.bin
--
|-- id18
| `-- aqm_P1800-id18.0200.bin
--
|-- id2
| `-- aqm_P1800-id2.0200.bin
At all, if you use -L 1
,
-L level
Max display depth of the directory tree.
you could better use (in bash) this syntax:
cd tstdir
echo */*qm*
or
printf "%s\n" */*qm*
and if only dir is needed:
printf "%s\n" */*qm* | sed 's|/.*$||' | uniq
At all, you could do this very quickly if pure bash:
declare -A array;for file in */*qm* ;do array[${file%/*}]='';done;echo "${!array[@]}"
This could be explained:
cd tstdir
declare -A array # Declare associative array, (named ``array'')
for file in */*qm* ;do # For each *qm* in a subdirectory from there
array[${file%/*}]='' # Set a entry in array named as directory, containing nothing
done
echo "${!array[@]}" # print each entrys in array.
... if there is no file matching pattern, result would display *
.
so for perfect the job, there left to do:
resultList=("${!array[@]}")
[ -d "$resultList" ] || unset $resultList
(This would be a lot quicker than
declare -A array
for file in */*qm*; do
[ "$file" == "*/*qm*" ] || array[${file%/*}]=''
done
echo "${!array[@]}"
)
find tstdir/ -type d -iname "qm*"
ortree -I "d*" -d tstdir/
– Rahul Patil Dec 21 '12 at 20:44