$ ls
1.txt 2.txt 3.txt
$ ls | wc
3 3 18
All three files has only 1 line, but ls|wc outputs '3'.
$ ls
1.txt 2.txt 3.txt
$ ls | wc
3 3 18
All three files has only 1 line, but ls|wc outputs '3'.
Try ls | cat
to see how ls formats output differently when piped, compared to when sent to terminal.
ls
, when outputting to anything other than a terminal, behaves like ls -1
(that's the digit 1
, not "ell") and outputs each name on a new line.
If you would want to count the number of line in the ls
output as it would have appeared had it not been piped at all, use ls -C
. The -C
option to ls
forces multi-column output regardless of where that output is directed.
That is, use
ls -C | wc
or, to just get the line count,
ls -C | wc -l
On the other hand, if you wanted to count the number of lines in the three files, individually, you would have used
wc -l -- *
This would, if each file contained exactly one line, result in the output
1 1.txt
1 2.txt
1 3.txt
3 total
That is, each file contains one line, and the total number of lines in the three files is three.
The difference between wc -l -- *
and ls -C | wc -l
(or, ls | wc
as you wrote), is from where wc
gets its input.
With ls -C | wc -l
, wc
reads from the output of ls
and would therefore count the number of lines that the ls
command produced. Not the number of lines in any file.
With wc -l -- *
, we tell wc
to read specific files. In this case, the files corresponding to the names that the wildcard ("filename globbing pattern") *
expands to.
wc -l -- *
is equivalent to wc -l -- 1.txt 2.txt 3.txt
if those are the only files in the directory.
Note that if one the files in the current directory is called -
, that wouldn't work properly as wc
interprets a -
argument as meaning standard input. One way to work around that would be to use wc -l ./*
instead (./-
is not special to wc
), but that means that ./
prefix will also show in the output of wc
.
ls
is giving you 3 columns which is different than single line, thus wc
is counting new line after each column end. In other words, ls
outputs formatted text, even though you don't see that. But wc
does.
ls
command, but from the individual files. – Kusalananda Nov 19 '18 at 20:25