3

What does the command :

ls | wc -l

do? I know

wc <filename>

gives lines, words, and characters, and

wc -l <filename> 

print the line count. But how it is being used with ls` is not clear. What does it do?

Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
gpuguy
  • 1,356

3 Answers3

7

On first glance, it counts the number of files in a directory (ls lists files, wc -l counts them).

But wait. Try this:

> mkdir test
> touch test/magic$'\n'newlines
> ls test | wc -l
2

Turns out the POSIX standard allows newlines in filenames. Because of this and other edge cases, the general method for counting the number of files in a directory is a lot more complicated.

There was once talk of adding a --zero flag to ls to allow such monstrosities to be split (the null character is illegal in POSIX filenames), but it never materialised due to resistance from the coreutils devs.

Doing ls | wc -l is probably safe for a casual check, but don't rely on it when you need standards-compliant code.

Anko
  • 4,526
  • 4
    Uch. +1 because you are entirely correct, but this ridiculous situation of allowing newlines in filenames is just... ugh. – evilsoup Feb 04 '14 at 22:23
2

There is a pipe | between two commands. Namely, ls which lists the contents of a directory and wc which will count the number of lines output from the ls command. (The pipe joins the output from first command to input of second, and so forth).

So the result is the number of files/directories found in this directory.

X Tian
  • 10,463
  • 1
    ls does a list without line jump so the command will not count the number of file and should return always 1, ls | wc -w should count the number of file (and it can't be used if space in filename) so the only goog stuff to use is ls -l | wc -l – Kiwy Feb 04 '14 at 13:44
  • 6
    @Kiwy most modern versions of ls automatically go to 'one file per line'-mode when the output is a pipe rather than an interactive terminal. – evilsoup Feb 04 '14 at 13:49
  • 1
    OK I didn't know. – Kiwy Feb 04 '14 at 14:02
1

ls lists files in a directory, and the command wc (aka. word count) returns the occurrences of lines in this example.

These commands can take a variety of switches (the -l after wc is called a switch). So you could have wc count the number of words or characters too.

Example

$ mkdir tst
$ cd tst
$ touch {1..5}
$ ls | wc -l
5

$ ls |wc
      5       5      10

NOTE: So here we have 5 "newlines", 5 words, and 10 characters. The 10 characters are the 1,2,3,4,5 and the corresponding \n (aka. newline character) that occurs after them in the output.

excerpt from the wc man page:

Print newline, word, and byte counts for each FILE, and a total line if more than one FILE is specified. With no FILE, or when FILE is -, read standard input.

So in our above examples we're using the "read standard input" which means take the input from the output of the ls command via the pipe (|). This is how in Unix you can chain commands together to do complicated things with very "basic" command line tools.

slm
  • 369,824