get just the integer from wc in bash
BashWcBash Problem Overview
Is there a way to get the integer that wc returns in bash?
Basically I want to write the line numbers and word counts to the screen after the file name.
output: filename linecount wordcount
Here is what I have so far:
files=`ls`
for f in $files;
do
if [ ! -d $f ] #only print out information about files !directories
then
# some way of getting the wc integers into shell variables and then printing them
echo "$f $lines $ words"
fi
done
Bash Solutions
Solution 1 - Bash
Most simple answer ever:
wc < filename
Solution 2 - Bash
Just:
wc -l < file_name
will do the job. But this output includes prefixed whitespace as wc
right-aligns the number.
Solution 3 - Bash
You can use the cut
command to get just the first word of wc
's output (which is the line or word count):
lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`
Solution 4 - Bash
wc $file | awk {'print "$4" "$2" "$1"'}
Adjust as necessary for your layout.
It's also nicer to use positive logic ("is a file") over negative ("not a directory")
[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}
Solution 5 - Bash
Sometimes wc outputs in different formats in different platforms. For example:
In OS X:
$ echo aa | wc -l
1
In Centos:
$ echo aa | wc -l
1
So using only cut may not retrieve the number. Instead try tr to delete space characters:
$ echo aa | wc -l | tr -d ' '
Solution 6 - Bash
The accepted/popular answers do not work on OSX.
Any of the following should be portable on bsd and linux.
wc -l < "$f" | tr -d ' '
OR
wc -l "$f" | tr -s ' ' | cut -d ' ' -f 2
OR
wc -l "$f" | awk '{print $1}'
Solution 7 - Bash
If you redirect the filename into wc
it omits the filename on output.
Bash:
read lines words characters <<< $(wc < filename)
or
read lines words characters <<EOF
$(wc < filename)
EOF
Instead of using for
to iterate over the output of ls
, do this:
for f in *
which will work if there are filenames that include spaces.
If you can't use globbing, you should pipe into a while read
loop:
find ... | while read -r f
or use process substitution
while read -r f
do
something
done < <(find ...)
Solution 8 - Bash
How about with sed
?
wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'
Solution 9 - Bash
If the file is small you can afford calling wc
twice, and use something like the following, which avoids piping into an extra process:
lines=$((`wc -l "$f"`))
words=$((`wc -w "$f"`))
The $((...))
is the Arithmetic Expansion of bash. It removes any whitespace from the output of wc
in this case.
This solution makes more sense if you need either the linecount or the wordcount.
Solution 10 - Bash
typeset -i a=$(wc -l fileName.dat | xargs echo | cut -d' ' -f1)
Solution 11 - Bash
Try this for numeric result:
nlines=$( wc -l < $myfile )
Solution 12 - Bash
Something like this may help:
#!/bin/bash
printf '%-10s %-10s %-10s\n' 'File' 'Lines' 'Words'
for fname in file_name_pattern*; {
[[ -d $fname ]] && continue
lines=0
words=()
while read -r line; do
((lines++))
words+=($line)
done < "$fname"
printf '%-10s %-10s %-10s\n' "$fname" "$lines" "${#words[@]}"
}
Solution 13 - Bash
To (1) run wc
once, and (2) not assign any superfluous variables, use
read lines words <<< $(wc < $f | awk '{ print $1, $2 }')
Full code:
for f in *
do
if [ ! -d $f ]
then
read lines words <<< $(wc < $f | awk '{ print $1, $2 }')
echo "$f $lines $words"
fi
done
Example output:
$ find . -maxdepth 1 -type f -exec wc {} \; # without formatting
1 2 27 ./CNAME
21 169 1065 ./LICENSE
33 130 961 ./README.md
86 215 2997 ./404.html
71 168 2579 ./index.html
21 21 478 ./sitemap.xml
$ # the above code
404.html 86 215
CNAME 1 2
index.html 71 168
LICENSE 21 169
README.md 33 130
sitemap.xml 21 21
Solution 14 - Bash
Solutions proposed in the answered question doesn't work for Darwin kernels.
Please, consider following solutions that work for all UNIX systems:
- print exactly the number of lines of a file:
wc -l < file.txt | xargs
- print exactly the number of characters of a file:
wc -m < file.txt | xargs
- print exactly the number of bytes of a file:
wc -c < file.txt | xargs
- print exactly the number of words of a file:
wc -w < file.txt | xargs
Solution 15 - Bash
There is a great solution with examples on stackoverflow here
I will copy the simplest solution here:
FOO="bar"
echo -n "$FOO" | wc -l | bc # "3"
Maybe these pages should be merged?
Solution 16 - Bash
Try this:
wc `ls` | awk '{ LINE += $1; WC += $2 } END { print "lines: " LINE " words: " WC }'
It creates a line count, and word count (LINE and WC), and increase them with the values extracted from wc (using $1 for the first column's value and $2 for the second) and finally prints the results.
Solution 17 - Bash
> "Basically I want to write the line numbers and word counts to the screen after the file name."
answer=(`wc $f`)
echo -e"${answer[3]}
lines: ${answer[0]}
words: ${answer[1]}
bytes: ${answer[2]}"
Outputs : myfile.txt lines: 10 words: 20 bytes: 120
Solution 18 - Bash
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"
Solution 19 - Bash
You have to use input redirection for wc
:
number_of_lines=$(wc -l <myfile.txt)
respectively in your context
echo "$f $(wc -l <"$f") $(wc -w <"$f")"