10

I wanted to list the content of a pwd and display only file starting with dot. I tried ls -a | grep ^\. but I cannot figure out why the output contains also the files which do not start with dot. For example:

Pictures
.pip
.pki
.profile
projects
Public

I know that I can achieve what I want with ls -ld .* I am just curious about this behaviour of grep which I can't explain.

3
  • See also: Why do I have to escape a “dot” twice? Commented Apr 5, 2015 at 14:33
  • Why not just ls -d .* to list all files starting with .?
    – Barmar
    Commented Apr 8, 2015 at 21:40
  • A cautionary note: Never pipe the output of ls into another command. Use find instead. ls has way too many ideosyncrasies to be trusted. See: Pitfall 1 at mywiki.wooledge.org/BashPitfalls - it made #1! The rest of the site is great too.
    – Joe
    Commented Apr 11, 2015 at 7:35

3 Answers 3

20

Quote the argument to grep, thus ls -a | grep '^\.'

The reason for this is that the shell handles \. and turns it back into plain ., which grep then treats as a single-character wildcard. If in doubt, always quote a string that contains (or might contain) a character that's special to the shell.

2
  • Why does shell ignore \?
    – ps-aux
    Commented Apr 5, 2015 at 11:25
  • \ is an escape sequence which makes the shell to treat the following character as a literal one. In this grep ^\\., \\ is treated by the shell as a single backslash and again the grep treats single backslash followed by the dot as literal dot. Commented Apr 5, 2015 at 11:28
11

You need to put the grep regex inside quotes.

ls -a | grep '^\.'

Note: Don't parse the output of ls command.

4
  • Why is it bad to parse the output of ls ?
    – ps-aux
    Commented Apr 5, 2015 at 11:25
  • From the link: In its default mode, if standard output isn't a terminal, ls separates filenames with newlines. This is fine until you have a file with a newline in its name. Commented Apr 5, 2015 at 12:09
  • @Michael Durrant: I'd suggest that allowing newlines in filenames is a major system bug.
    – jamesqf
    Commented Apr 5, 2015 at 17:18
  • @jamesqf - see newlines in filenames (especially sml's answer). Commented Apr 5, 2015 at 19:08
0

If you execute cmd ls -a | grep ^\. then grep do not consider "\" as a special character and meaning of "." do not get escaped.

When we use cmd ls -a | grep "^\." then grep considers "\" as a special character and meaning of "." gets escaped. It will give you a result as expected.

If you want to use grep cmd without quotes then you should escape "\" character also. You can have expected result without double quotes by following command. ls -a | grep ^\\.

For details about meaning of special characters in Regex, refer following link. http://www.regular-expressions.info/quickstart.html

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .