سؤال

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

هل كانت مفيدة؟

المحلول

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' '`

نصائح أخرى

Most simple answer ever:

wc < filename 

Just:

wc -l < file_name

will do the job. But this output includes prefixed whitespace as wc right-aligns the number.

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"'}

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 ' '

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}'

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 ...)

How about with sed?

wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'
typeset -i a=$(wc -l fileName.dat  | xargs echo | cut -d' ' -f1)

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.

Try this for numeric result:
nlines=$( wc -l < $myfile )

"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

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[@]}"
}

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

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.

files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"

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")"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top