zshglobhidden-files

zsh glob to find directories that are empty or that only contain a .DS_Store


Is there any zsh glob that will find directories that are either empty or that only contain a .DS_Store file?

I know that the (/^F) glob flag combo will find empty directories, but I also want to include directories that contain only a .DS_Store file but that contain no other nodes (files, directories, etc.).

For my purposes, if I cannot filter out specifically .DS_Store, filtering out either all hidden files (.*(.)) or all hidden nodes (.*) will suffice.


Solution

  • Not simple, but we could do:

    setopt extendedglob  # for '~' and '#q' in the `[[ … ]]' form
    setopt globstarshort # shortcut for '**/*' to '**'
    
    print -rC1 -- **(DN/^F,/e['[[ -z $REPLY/*~*/.DS_Store(#qoNDNY1) ]]'])
    

    lists empty directories or directories in which any file does not exist other than .DS_Store (in other words: only .DS_Store exits).

    setopt extendedglob globstarshort
    rm -rf tester
    mkdir tester
    cd tester
    mkdir empty dsstore-only more-dotfiles more
    touch dsstore-only/.DS_Store more-dotfiles/{.DS_Store,.DS_Store.old} more/{.DS_Store,more}
    mkdir child
    cp -a ^child child
    tree -a
    #>> .
    #>> ├── child
    #>> │   ├── dsstore-only
    #>> │   │   └── .DS_Store
    #>> │   ├── empty
    #>> │   ├── more
    #>> │   │   ├── .DS_Store
    #>> │   │   └── more
    #>> │   └── more-dotfiles
    #>> │       ├── .DS_Store
    #>> │       └── .DS_Store.old
    #>> ├── dsstore-only
    #>> │   └── .DS_Store
    #>> ├── empty
    #>> ├── more
    #>> │   ├── .DS_Store
    #>> │   └── more
    #>> └── more-dotfiles
    #>>     ├── .DS_Store
    #>>     └── .DS_Store.old
    #>>
    #>>10 directories, 10 files
    
    print -rC1 -- **(DN/^F,/e['[[ -z $REPLY/*~*/.DS_Store(#qoNDNY1) ]]'])
    #>> child/dsstore-only
    #>> child/empty
    #>> dsstore-only
    #>> empty
    

    Note: some references:

    Glob Qualifires:
    ...
    More than one of these lists can be combined, separated by commas. The whole list matches if at least one of the sublists matches (they are `or'ed, the qualifiers in the sublists are `and'ed). Some qualifiers,

    --- Glob Qualifires, zshexpn(1)

    Conditional Expressions:
    ...
    Filename generation is not performed on any form of argument to conditions. However, it can be forced in any case where normal shell expansion is valid and when the option EXTENDED_GLOB is in effect by using an explicit glob qualifier of the form (#q) at the end of the string.

    --- Conditional Expressions, zshmisc(1)