Unix Shell - Piping a loop's printf output kills a variable...

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > April 2005 > Piping a loop's printf output kills a variable...





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Piping a loop's printf output kills a variable...
matt_left_coast

2005-04-28, 2:49 am

I have a loop that outputs a formated "report" of counts of certain
occurrences of different words that I would like to sort with grand total
at the end.

The script without a sort pipe gives the Grand Total:

infile=filename
grand=0

for var in $srtlist
do
count=`grep -c $var $infile`
((grand=$grand + $count))

printf "$count\t$var"
done

echo "Grand Total: $grand"

The script with a sort pipe does not:


infile=filename
grand=0

for var in $srtlist
do
count=`grep -c $var $infile`
((grand=$grand + $count))

printf "$count\t$var"
done | sort -n # sort added here!

echo "Grand Total: $grand"


It seems to be the pipe and not the sort. The variable does not work if I do
any pipe.

If anyone could point me in a direction where I can find the answer to
this...


Thanks
matt_left_coast

2005-04-28, 2:49 am

matt_left_coast wrote:

> I have a loop that outputs a formated "report" of counts of certain
> occurrences of different words that I would like to sort with grand total
> at the end.
>
> The script without a sort pipe gives the Grand Total:
>
> infile=filename
> grand=0
>
> for var in $srtlist
> do
> count=`grep -c $var $infile`
> ((grand=$grand + $count))
>
> printf "$count\t$var"
> done
>
> echo "Grand Total: $grand"
>
> The script with a sort pipe does not:
>
>
> infile=filename
> grand=0
>
> for var in $srtlist
> do
> count=`grep -c $var $infile`
> ((grand=$grand + $count))
>
> printf "$count\t$var"
> done | sort -n # sort added here!
>
> echo "Grand Total: $grand"
>
>
> It seems to be the pipe and not the sort. The variable does not work if I
> do any pipe.
>
> If anyone could point me in a direction where I can find the answer to
> this...
>
>
> Thanks



BTW, I forgot to say this is a bash script...
Ed Morton

2005-04-28, 2:49 am



matt_left_coast wrote:
> matt_left_coast wrote:
>
>
>
>
>
> BTW, I forgot to say this is a bash script...


See question 36 in the FAQ (http://home.comcast.net/~j.p.h/cus-faq.html#JJ).

By the way, I believe this:

((grand=$grand + $count))

should really be written as this:

grand=$(( grand + count ))

for portability. You can use "$"s in front of the variables inside the
brackets if you like but they aren't required.

Also, the above will not count occurrences of words, but ocurrences of
strings, so if you have "the" and "there" in the file and "the" is one
of the strings in "$srtlist", then it'll get counted twice. If you
really want words (in the case below, I'm assuming that's
space-separated strings otherwise you need to set FS to match any
non-alphabetic character), I'd suggest an awk script like this one
(untested and assumes your $srtlist is blank-separated):

awk -vs="$srtlist" 'BEGIN{OFS="\t"; c=split(s,vars," ")
for(i=1;i<=c;i++) strlist[vars[i]]++ }
{for (i=1; i<=NF; i++) if ($i in strlist) count[$i]++}
END {for (var in count) print count[var], var}' "$infile"

The above doesn't sort the output. You can do that in gawk using
"asort()" before the loop in the END section if you like (though you'd
need to pad your count with leading zeros since that's an alphabetic
sort) but I'd just pipe the output to "sort" and sum the result, e.g.:

awk -vs="$srtlist" 'BEGIN{OFS="\t";c=split(s,vars," ")
for(i=1;i<=c;i++) strlist[vars[i]]++ }
{for (i=1; i<=NF; i++) if ($i in strlist) count[$i]++}
END {for (var in count) print count[var], var}' "$infile" |
sort -n |
awk '{grand += $1;print}END{printf "Grand Total: %s\n",grand}'


Regards,

Ed.
Chris F.A. Johnson

2005-04-28, 2:49 am

On Thu, 28 Apr 2005 at 03:30 GMT, matt_left_coast wrote:
> I have a loop that outputs a formated "report" of counts of certain
> occurrences of different words that I would like to sort with grand total
> at the end.
>
> The script without a sort pipe gives the Grand Total:
>
> infile=filename
> grand=0
>
> for var in $srtlist
> do
> count=`grep -c $var $infile`
> ((grand=$grand + $count))
>
> printf "$count\t$var"
> done
>
> echo "Grand Total: $grand"
>
> The script with a sort pipe does not:
>
>
> infile=filename
> grand=0
>
> for var in $srtlist
> do
> count=`grep -c $var $infile`
> ((grand=$grand + $count))
>
> printf "$count\t$var"
> done | sort -n # sort added here!
>
> echo "Grand Total: $grand"
>
>
> It seems to be the pipe and not the sort. The variable does not work if I do
> any pipe.
>
> If anyone could point me in a direction where I can find the answer to
> this...


The elements of a pipeline are each executed in their own subshell.
For ways to deal with it, see the FAQ:

<http://home.comcast.net/~j.p.h/cus-faq.html#JJ>

--
Chris F.A. Johnson <http://cfaj.freeshell.org>
========================================
==========================
Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress
<http://www.torfree.net/~chris/books/ssr.html>
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com