24

I tried to display only hidden files but don't know how to do it.

That is working (but matching also dots in other places)

ls -la | grep '\.'

Was trying adding ^ but didn't find the solution.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
user3014282
  • 415
  • 2
  • 4
  • 6
  • 2
    Parsing `ls` is never a wonderful idea, but what you tried would have worked if you used the anchor `^` to denote the start of match. `ls -la | grep '^\.'` – devnull Apr 09 '14 at 13:15
  • 4
    No it won't, the filename isn't the beginning of the line with the -l flag. `ls -la | awk '$9 ~ /^\./'` will. – yoonix Apr 09 '14 at 22:23

10 Answers10

33

ls -ld .* will do what you want.

Flup
  • 8,017
  • 2
  • 33
  • 50
10
find . -type f -name '\.*' -print 

Must work if you want list every hidden file down in the directory hierarchy.

terdon
  • 234,489
  • 66
  • 447
  • 667
periket2000
  • 2,348
  • 1
  • 13
  • 11
8

An improvement on Flup's answer:

ls -lad .[!.]* ..?*

This will list all files whose name starts with a dot and that are neither . nor ...

Note that if you want to pipe the output of ls to grep (which, as pointed out by devnull, is never a good idea), make sure you use \ls or command ls because if ls is aliased to show you colored output (as it is on Debian for example), its output contains ANSI escape sequences to create colored output, which will trip up your grep if its pattern is anchored at the start of line.

Joseph R.
  • 38,849
  • 7
  • 107
  • 143
  • 2
    You can use `-A` (instead of `-a`) to ignore `.`, `..`. – OJFord Jul 03 '17 at 19:38
  • @OJFord+ `-A` differs from `-a` for directories that `ls` descends into, but both are (equally) ignored and useless for names specified on the command line with `-d` in effect. Also if `ls` is aliased to `--color=auto` then piping is okay; only `--color=always` or `--color` causes trouble. – dave_thompson_085 Nov 14 '18 at 07:18
  • Please explain the `.[!.]* ..?*` part. Is this some kind of bash-ism? – Totor Oct 29 '21 at 01:31
2

If you want to parse ls output, you must add ^ at beginning of regex and don't use -l option. Using -l causes each line output start with file or folder permission information, not file or folder name. So you should use like this:

ls -Ad | grep '^\.'

Or you can do with printf bash builtin:

printf "%s\n" .*

If you use zsh, you can use:

print -l .*
cuonglm
  • 150,973
  • 38
  • 327
  • 406
1

Here are two other ways to find hidden files only.

find . -maxdepth 1 -name ".*" -type f -ls

or

find . -maxdepth 1 -name ".*" -type f -printf "%P \n"

Use -maxdepth to specify how far you want to search in the directory tree.

Valentin Bajrami
  • 9,244
  • 3
  • 25
  • 38
0

The solution of val0x00ff is really good, but it forgets hidden directories.

If you want hidden files and hidden directories, without . and .. :

find -maxdepth 1 -regex '\./\..+' -printf "%P\n"
piroux
  • 101
  • Your suggestion fails on VMware ESXi (list no files and no directories) and sort of fails on Linux too (with maxdepth > 1, it also lists any files in a directory starting with a .), but this works on both Linux and ESXi: `find . \( -type f -o -type d \) -name '\.*' -print`; apply `maxdepth` where needed. – Jeroen Wiert Pluimers May 06 '18 at 07:38
0

Below one is much compact and support many variants

1) Display hidden files, directories and sub-directories

find . | grep "^\./\."

2) Display hidden directories and sub-directories only

find . -type d | grep "^\./\."

3) Display hidden files only in current and sub-directories

find . -type f | grep "^\./\."

4) Display hidden files and directories in current folder

find . -maxdepth 1 | grep "^\./\."

GLK
  • 101
  • 2
0

You can try:

find . -maxdepth 1 -type f -name '\.*' -print
find . -maxdepth 1 \( -type f -o -type d \) -name '\.*' -print

Of course you can use different maxdepth values or remove it completely. Very helpful if you want to explore between directories (-type d) or regular files (type f) or both, and combine with other functions like:

(e.g. last modified time, based on @piroux example - completed by @jeroen-wiert-pluimers )

find . -maxdepth 1 \( -type f -o -type d \) -name '\.*' -exec stat -c %y {} \; -printf "%P\t"
azbarcea
  • 142
  • 6
-1

You can try :

ls -a |grep -E  "^\."

^ indicates it's the beginning of content with regexp

  • 1
    A duplicate of [another answer](https://unix.stackexchange.com/a/123944/117549) from 3 years ago ... – Jeff Schaller Nov 28 '17 at 11:55
  • I saw the previous answer , it's not duplicate , and definitely "ls -a" and "ls -Ad" don't have the same meaning . "-a" means list all including files/directories begins with "." -A means list all but excluding "." , ".." and directory content. – Lingjing France Nov 28 '17 at 12:14
-1

Try this:

    ls -ap | grep -v / | grep '^\.'
  • Welcome to the site, and thank you for your contribution. Please note, though, that the OP seems to be interested in the "long listing" format (`-l`), whereas your approach relies on the "filenames only" ouptut of `ls -a`, and is therefore likely not what the OP wants ... – AdminBee May 28 '20 at 10:48
  • This will also fail if a filename contains a newline character. it is generally a bad idea to solve this sort of thing by attempting to parse the output of `ls`. – terdon May 28 '20 at 12:30