25

I want to carry out some action (say chown) on all the hidden files in a directory.

I know that this .* is not a good idea because it will also find the current . and parent .. directories (I know that rm will fail to operate on . and .. but other commands, including chown and chmod, will happily take effect)

But all my hidden files have different names!

How should I glob for all hidden files while excluding . and .. ?

0
24

In Bash use:

GLOBIGNORE=".:.."

to hide the . and .. directories. This also sets the dotglob option: * matches both hidden and non-hidden files.

You can also do:

shopt -s dotglob

Gilles :)

1
  • 1
    IMO this is better than the accepted answer. Easier to remember, infinitely more intuitive, and able to be stuffed into .bashrc to make it permanent if one so wishes (I know I almost never want * to mean "non-dotfiles only").
    – jcgoble3
    Sep 27 at 4:30
21

You can use the following extglob pattern:

.@(!(.|))
  • . matches a literal . at first

  • @() is a extglob pattern, will match one of the patterns inside, as we have only one pattern inside it, it will pick that

  • !(.|) is another extglob pattern (nested), which matches any file with no or one .; As we have matched . at start already, this whole pattern will match all files starting with . except . and ...

extglob is enabled on interactive sessions of bash by default in Ubuntu. If not, enable it first:

shopt -s extglob

Example:

$ echo .@(!(.|))
.bar .foo .spam
5
  • 1
    This is clearly an awesome thing I need to learn about! Thank you for teaching
    – Zanna
    Sep 26 '16 at 10:38
  • @Zanna Glad i could help :)
    – heemayl
    Sep 26 '16 at 10:39
  • 2
    What is the purpose of the @()? Simple .!(.|) seems to work identically. Sep 26 '16 at 16:49
  • 1
    I know that this is old, but I have the same question as @KyleStrand. In my tests, !(.|) works the same. Is there any purpose behind @() in this context? Apr 2 '17 at 7:26
  • Is the bang character a negation? It is not mentioned, and reading your explanation, I get the impression, that the pattern matches dot and doubledot, but you clearly describe files which match a starting dot, except just those two. May 14 '19 at 21:21
10

You can use a find command here. For example something like

find -type f -name ".*" -exec chmod 775 {} \;

This will find hidden files and change permissions


Edit to include the comment by @gerrit:

find -type f -maxdepth 1 -name ".*" -exec chmod 775 {} \;

This will limit the search top the current directory instead of searching recursively.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.