Home > OS >  Counting Python files with bash and awk always returns zero
Counting Python files with bash and awk always returns zero

Time:05-31

I want to get a number of python files on my desktop and I have coded a small script for that. But the awk command does not work as is have expected. script

ls -l | awk '{ if($NF=="*.py") print $NF; }' | wc -l

I know that there is another solution to finding a number of python files on a PC but I just want to know what am i doing wrong here.

CodePudding user response:

ls -l | awk '{ if($NF=="*.py") print $NF; }' | wc -l

Your code does count of files literally named *.py, you should deploy regex matching and use correct GNU AWK syntax, after fixing that, your code becomes

ls -l | awk '{ if($NF~/[.]py$/) print $NF; }' | wc -l

note [.] which denote literal . and $ denoting end of string. Your code might be further ameloriated, as there is not need to use if here, as pattern-action will do that is

ls -l | awk '$NF~/[.]py$/{ print $NF; }' | wc -l

Morever you might easily implemented counting inside GNU AWK rather than deploying wc -l as follows

ls -l | awk '$NF~/[.]py$/{t =1}END{print t}'

Here, t is increased by 1 for every describe line, and after all is processed, that is in END it is printed. Observe there is no need to declare t variable in GNU AWK.

CodePudding user response:

Don't try to parse the output of ls, see https://mywiki.wooledge.org/ParsingLs.

Beyond that your awk script is failing because $NF=="*.py" is doing a literal string partial comparison of the last sting of non-spaces against *.py when you probably wanted a regexp comparison such as $NF~/*.py$/ and your print $NF would fail for any file names containing spaces.

If you really want to involve awk in this for some reason then, assuming the list of python files doesn't exceed ARG_MAX, it'd be:

awk 'BEGIN{print ARGC-1; exit}' *.py

but you could just do it in bash:

shopt -s nullglob
files=(*.py)
echo "${#files[@]}"

or if you want to have a pipe to wc -l for some reason and your files can't have newlines in their names then:

printf '%s\n' *.py | wc -l

CodePudding user response:

gfind . -maxdepth 1 -type f -name "*.py" -print0 | 

     {m,g}awk 'END { print   NR }' RS='\0' FS='^$'
   or
     {m,g}awk 'END { print --NF }' RS='^$' FS='\0'

879
  • Related