Linux: How to list all files/directories, using only ls

17,998

Solution 1

Unix utilities were meant to be used as filters, so the answer given makes sense since it best approximates a real-world application.

You do understand, though, that grep "\." matches everything with a "period" (hence, extension), and grep -v "\." matches everything else (i.e., the complement).

It is hard to make the command any more precise than what it is already, since who can say what's intended to be an extension, and what's not?


Part 2: ls testfiles | grep "^[^.]*$"

A bracket expression is a list of characters enclosed by [ and ]. It matches any single character in that list; if the first character of the list is the caret ^ then it matches any character not in the list. For example, the regular expression [0123456789] matches any single digit.

http://unixhelp.ed.ac.uk/CGI/man-cgi?grep

So ^[^.]*$ actually means:

Anything that begins and ends with a string of characters, each of which is not a period.

The first caret is not a negation, it means begins with. The second caret is the "not" signifier.

Solution 2

Now, just to understand how ls regex works, could someone please explain to me how this would be [done] by using only ls?

You could do it with the ignore flag:

ls -I '*.*'

Note - works on CentOS 6, not sure about other Linux distributions.

Solution 3

Correction:

^      -> pattern starts at the beginning of the string
[^.]   -> matches something that is not a dot
*      -> repeated zero or more times
$      -> and must continue to match (only non-dot items) until the end

Thus, it must have only non-dot things from the beginning to the end.

Share:
17,998
m.spyratos
Author by

m.spyratos

Updated on June 04, 2022

Comments

  • m.spyratos
    m.spyratos almost 2 years

    This is a question given at university.

    The question is: List all files/directories inside testfiles folder, that have no extension.
    The right answer given is this:

    ls testfiles | grep -v "\."
    

    Now, just to understand how ls regex works, could someone please explain to me how this would be by using only ls? Moreover, I would appreciate any example that also uses the dollar sign $, to specifically state that the name ends with .[a-z].

    Any help, really appreciated.

    One more thing! Another answer to this question is using:

    ls testfiles | grep "^[^.]*$"
    

    How is that read? I read ^[^.]*$ like this:

    ^      -> does not contain
    [^.]   -> starts with a dot
    *      -> repeated zero or more times
    $      -> till the end
    

    I would like someone to correct me on this... Thanks!

    • Konrad Rudolph
      Konrad Rudolph about 11 years
      I don’t think you can do that using only ls.
    • Boris the Spider
      Boris the Spider about 11 years
      ls uses extended glob syntax, not regex. Take a look at this for ideas.
    • chepner
      chepner about 11 years
      [^.] as a regular expression matches any single character except a period.
    • Boris the Spider
      Boris the Spider about 11 years
      Your regex analysis isn't quite right, a ^ at the start is the start anchor. So the pattern is really matching any number of characters that aren't a dot from the start to the end.
    • Charles Duffy
      Charles Duffy about 11 years
      In the real world, ls would be the wrong tool for this job. See mywiki.wooledge.org/ParsingLs
    • Artem
      Artem about 11 years
      You've lost me at "|". If the requirement is 'only ls', then what is grep doing in there?
    • m.spyratos
      m.spyratos about 11 years
      @bmargulies, that was the correct answer given. I am asking if that can be translated only using ls.
    • m.spyratos
      m.spyratos about 11 years
      @bmorris591, Thank you.
    • Charles Duffy
      Charles Duffy about 11 years
      @bmorris591 ls knows nothing about either globs or regexes; it's the shell that interprets globs, and hands ls a list of files on its argv array.
  • Sebastian
    Sebastian about 11 years
    "So ^[^.]*$ actually means: Anything that begins and ends with any character that's not a period." No, it means anything that has only non-period characters from beginning to end.
  • ktm5124
    ktm5124 about 11 years
    I meant, anything that begins and ends with a string of characters each of which is not a period... which is a wordy way of saying what you said.
  • m.spyratos
    m.spyratos about 11 years
    I could yes! But basically I was looking into how to convert the grep into ls. That means, by using regular expressions. -I does the trick for sure, but it's not exactly what I was looking for. I think borries591 answer was the best: "ls uses extended glob syntax, not regex". Still though, thank you...
  • Charles Duffy
    Charles Duffy about 11 years
    @m.spyratos That's actually not quite true -- ls doesn't recognize either glob syntax or regexes itself, unless you use extensions such as the -I flag given here. The shell converts globs into a list of files before it ever starts ls.