Hi, I'm trying to print all the name of the files in the working directory as well as the number of lines and words that each file has next to them
i.e
file1.txt 71 431
file2.bash 31 511
I tried using a script:
1 2 3 4
#!/bin/bash
ls * ;
wc -l ls *;
wc -w ls *;
But instead it prints
wc: ls: No such file or directory
73 abc.txt
5 cin.bash
43 formula
6 chem
127 total
wc: ls: No such file or directory
421 abc.txt
12 cin.bash
136 formula
24 chem
593 total
Can anyone tell me what I'm doing wrong or give some advice?
You are asking to count the words in all the named files, including 'ls', which doesn't exist.
(Try creating a file named 'ls' to prove to yourself that it is the issue.)
The 'ls' command is for humans. The shell properly handles wildcards for you, so you don't need to try to insert a command to do it. Chances are it would produce results unusable for the command anyway.
EXPANSION
Expansion is performed on the command line after it has been split into words. There are
seven kinds of expansion performed: brace expansion, tilde expansion, parameter and vari-
able expansion, command substitution, arithmetic expansion, word splitting, and pathname
expansion.
Pathname Expansion
After word splitting, unless the -f option has been set, bash scans each word for the
characters *, ?, and [. If one of these characters appears, then the word is regarded as
a pattern, and replaced with an alphabetically sorted list of file names matching the
pattern.
man wc:
NAME
wc - print newline, word, and byte counts for each file
SYNOPSIS
wc [OPTION]... [FILE]...
When you write wc * the wc never sees the *, unless bash fails to expand the word. What wc does see, is filenames. Note though that subdirectorynames are included.
One could control that with a loop:
for F in * ; do [[ -f "$F" ]] && wc -lw "$F"; done
C++ pseudo-equivalent:
1 2 3 4 5
for ( auto F : directorycontents ) {
if ( isRegularFile( F ) ) {
wc( F, WC::lines & WC::words );
}
}
The other thing; you did desire "name lines words", but the wc shows "lines words name". Mere bash parameter expansion could do this, but there are other ways too: