Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I have a directory that contains thousands of files, some of them are hidden.

The command ls -a list all files, including hidden ones, but I need just to list hidden files.

What command should I use?

share|improve this question
add comment

8 Answers 8

up vote 11 down vote accepted

The command :

ls -ld .?* 

Will only list hidden files .

Explain :

 -l     use a long listing format

 -d, --directory
              list  directory entries instead of contents, and do not derefer‐
              ence symbolic links

.?* will only state hidden files 
share|improve this answer
2  
You don't need the two question marks in there, the * covers it ( ? only matches any single character, * matches any number of them ). –  psusi May 19 at 0:50
5  
@psusi, I think the intent is to exclude . and .. from the match. However it will also exclude (perfectly legal) single-character hidden filenames such as .a, .1 and so on. Perhaps a better extended glob would be .!(|.) i.e. literal dot followed by anything except nothing or another (single) dot i.e. ls -d .!(|.) –  steeldriver May 19 at 1:25
1  
@steeldriver you should write an answer with that command. –  Lucio May 19 at 1:27
    
Sorry about the double rollback, I was confused. –  terdon May 19 at 2:56
    
@steeldriver, neat, the ?? version does exclude "." and "..". This seems to be the result of an interesting quirk: neither ? nor * will match a dot, but the ? must match something otherwise the name is ignored. –  psusi May 19 at 3:37
show 1 more comment
ls -d .!(|.)

Does exactly what OP is looking for .

share|improve this answer
add comment

If you just want the files in your current directory (no recursion), you could do

echo .[^.]*

That will print the names of all files whose name starts with a . and is followed by one or more non-doc characters. Note that this will fail for files whose name starts with consecutive dots, so for example ....foo will not be shown.

You could also use find:

find -mindepth 1 -prune -name '.*'

The -mindepth ensures we don't match . and the -prune means that find won't descend into subdirectories.

share|improve this answer
add comment
ls -ad .*

works for me in Bash.

share|improve this answer
add comment

Using find and awk,

find . -type f | awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

Explanation:

find . -type f --> List all the files in the current directory along with it's path like,

./foo.html
./bar.html
./.foo1

awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

/ as field separator awk checks for the last field staring with a dot or not. If it starts with a dot, then it prints the last field of that corresponding line.

share|improve this answer
    
You could just use find -type f. You don't need to explicitly set the search path or -name "*". –  terdon May 19 at 3:08
    
Thanks :D @terdon –  Avinash Raj May 19 at 3:10
add comment

I think that you can do it with following command.

ls -a | grep "^\." | grep -v "^\.$" | grep -v "^\..$"

ls -a command you entered, that shows all files and directories in current working directory.

grep "^\." command I appended, that filters output to shows only hidden files(It's name starts with ".").

grep -v "^\.$" | grep -v "^\..$" command I appended, that filters output to exclude ., ..(They are current and parent directory).

If some filenames can have more than a line with "\n", above example could be incorrect.

So I suggest following command to solve it issue.

find -maxdepth 1 -name ".[!.]*"
share|improve this answer
6  
You should never parse the output of ls. –  Radu Rădeanu May 19 at 8:50
    
@RaduRădeanu I saw your comment, It's so good. I edited my answer again. Thank you to your comment. –  xiaodongjie May 21 at 3:03
add comment

You can also use:

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

This will allow you to display normal hidden files and hidden files which begin with 2 or 3 dots for example : ..hidden_file

share|improve this answer
1  
With this I get all hidden files twice. –  Tuknutx May 19 at 9:02
add comment

find is usually a better option for complicated searches than using name globbing.

find . -mindepth 1 -maxdepth 1 -name '.*'

or

find . -mindepth 1 -maxdepth 1 -name '.*' -o -name '*~'

find . searches current directory

-mindepth 1 excludes . and .. from the list

-maxdepth 1 limits the search to the current directory

-name '.*' find file names that start with a dot

-o or

-name '*~' find file names that end with a tilde (usually, these are backup files from text editing programs)

However, this and all of the other answers miss files that are in the current directory's .hidden file. If you are writing a script, then these lines will read the .hidden file and display the file names of those that exist.

if [[ -f .hidden]] # if '.hidden' exists and is a file
then
    while read filename # read file name from line
    do
        if [[ -e "$filename" ]] # if the read file name exists
        then
            echo "$filename" # print it
        fi
    done < .hidden # read from .hidden file
fi
share|improve this answer
    
What's the .hidden file? Why would there ever be a file called .hidden that contains the file names? Anyway, if there is one why would you do something that complex when all you would need would be cat .hidden? Your find command is correct(ish) but the -name '*~' is irrelevant. Files that end in tildes are backup files but not hidden in any way. –  terdon May 21 at 3:19
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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