0

I ran into a problem I am trying to solve but can't think about a way without doing the whole thing from the beginning. My script gets an extension and searches for every .extension file recursively, then outputs the "filename:row #:word #". I would like to print out the total amount of row #-s found in those files too. Is there any way to do it using the existing code?

for i in find . -name '*.$1'|awk -F/ '{print $NF}'
do
  echo "$i:`wc -l <$i|bc`:`wc -w <$i|bc`">>temp.txt
done

sort -r -t : -k3 temp.txt

cat temp.txt
jww
  • 97,681
  • 90
  • 411
  • 885
  • strings within single quotes aren't interpolated. Are you sure that you need to search for files with extension `.$1` ? – user3159253 Apr 07 '18 at 10:31
  • I've successfully solved it using two simple variables. As a beginner I couldn't get the code going properly yet, but I'll ask for some correction a bit later. Anyways if somebody was curious I'm posting the code below: –  Apr 07 '18 at 10:38
  • ossz=0 maxi=0 mini=100000000 for i in `find . -name '*.$1'|awk -F/ '{print $NF}'` do echo "$i:`wc -l <$i|bc`:`wc -w <$i|bc`">>temp.txt if ((`wc -w <$i` > maxi)) maxi=`wc -w <$i` if ((`wc -w<$i` < mini)) mini=`wc -w <$i` ossz=ossz+`wc -l <$i` sort -r -t : -k3 temp.txt cat temp.txt echo "$maxi:$mini" echo $ossz –  Apr 07 '18 at 10:45

2 Answers2

1

I think you're almost there, unless I am missing something in your requirements:

#!/bin/bash
total=0
for f in `find . -name "*.$1"` ; do
        lines=`wc -l < $f`
        words=`wc -w < $f`
        total=`echo "$lines+$total" | bc`
        echo "* $f:$lines:$words"
done
echo "# Total: $total"

Edit:
Per recommendation of @Mark Setchel in the comments, this is a more refined version of the script above:

#!/bin/bash
total=0
for f in `find . -name "*.$1"` ; do
        read lines words _ < <(wc -wl "$f")
        total=$(($lines+$total))
        echo "* $f:$lines:$words"
done
echo "# Total: $total"

Cheers

lubumbax
  • 255
  • 2
  • 9
  • You can get the both the word count and line count of a file in one go. Users may not thank you for running `wc` twice on a bunch of multi-gigabyte files. Also, `bash` can do addition of integers on its own without `bc`, e.g. `((total=total+lines))`. Also, you should generally double-quote filenames, like where you use `wc -l < $f`. – Mark Setchell Apr 07 '18 at 11:25
  • Thank you for all your help. I got the script running, now trying to do some server-related scripts. Props for every tip, they are appreciated! –  Apr 07 '18 at 11:43
  • Thanks @MarkSetchell, all very valid points. I wasn't neither too sure that the above were the actual requirements hence didn't spent much time on "refining" the solution. Loved the tip with read to "swallow off" the file name string from the output of 'wc'. – lubumbax Apr 07 '18 at 11:55
0

This is a one-liner printing the lines found per file, the path of the file and at the end the sum of all lines found in all the files:

find . -name "*.go" -exec wc -l {} \; | awk '{s+=$1} {print $1, $2} END {print s}'

In this example if will find for all files ending *.go then will execute use wc -l to get the number of lines and print the output to stdout, awk then is used to sum all the output of column 1 in the variable s the one will be only printed at the end: END {print s}

In case you would also like to get the words and the total sum at the end you could use:

find . -name "*.go" -exec wc {} \; | \
    awk '{s+=$1; w+=$2} {print $1, $2, $4} END {print "Total:", s, w}'

Hope this can give you an idea about how to format, sum etc. your data based on the input.

nbari
  • 25,603
  • 10
  • 76
  • 131
  • Thank your for the fine answer, I believe this is a whole another level of understanding shell scripts since I'm struggling to get some scripts going atm. :D –  Apr 08 '18 at 09:52