Search code examples
bashgrepfindbash-function

Bash function to process all dotfiles in a directory excluding directories


I am looking to create a bash function to filter all the dotfiles (no directories) in a selected directory. I only need the file name, not the full path.

For the moment, i only have this command:

find . -maxdepth 1 -type f -print0

which prints all the files excluding the dirs. Now i still have to exclude the non-dotfiles. So i've try to pipe the output to grep, like so:

find . -maxdepth 1 -type f -print0 | grep "^\."

and it didn't seem to work. ->

Binary file (standard input) matches

Do you guys have an elegant solution to this?

Thanks!


Solution

  • If you want only dot-files:

    find . -maxdepth 1 -type f -name '.*' -printf '%f\0'
    

    The test -name '.*' selects dot files. Since -name accepts globs, . means a literal period and * means any number of any character.

    The action -printf '%f\0' will print NUL-separated filenames without the path.

    If your name selection criteria becomes more complex, find also offers -regex which selects files based on regular expressions. GNU find understands several different dialects of regular expression. These can be selected with -regextype. Supported dialects include emacs (default), posix-awk, posix-basic, posix-egrep, and posix-extended.

    Mac OSX or other BSD System

    BSD find does not offer -printf. In its place, try this:

    find . -maxdepth 1 -type f -name '.*' -exec basename {} \;
    

    Note that this will be safe all file names, even those containing difficult characters such as blanks, tabs or newlines.

    Putting the dot files into a bash array

    If you want to get all dot files and directories into an array, it is simple:

    all=(.*).
    

    That is safe for all file names.

    If you want to get only regular files, not directories, then use bash:

    a=(); while IFS= read -r -d ''; do a+=("$(basename "$REPLY")"); done < <( find $HOME -maxdepth 1 -type f -name '.*' -print0 )
    

    This is also safe for all file names.