Home > Enterprise >  Bash script - How to sum and aggregate output of cycle for,while
Bash script - How to sum and aggregate output of cycle for,while

Time:12-02

I wrote a script which count number of lines in each file:

todays_day=$(date  %d) 
if ((todays_day==1)); then
  month="$(date --date='1 day ago'  %y%m)"
else
  month="$(date  %y%m)"
fi
for catalog in $(find ./ -type d -name "$month")
   do 
    sum=0
   find $catalog -type f -name "*.z" | while read FN 
   do   
    sum=$((sum $(zcat $FN | awk 1 | wc -l)))
    echo "no of lines $sum;source $(find $catalog -type d );data $(date  "%d-%m-%Y %T")"
    done
done

Now it accumulate number of lines and shows in result

no of lines 3;source ./AXE/CNA5/LBN/2211;data 01-12-2022 17:35:49
no of lines 6;source ./AXE/CNA5/LBN/2211;data 01-12-2022 17:35:50
no of lines 9;source ./AXE/CNA5/LBN/2211;data 01-12-2022 17:35:50
no of lines 13;source ./AXE/CNA5/LBN/2211;data 01-12-2022 17:35:51
no of lines 3;source ./AXE/TELLIN/2211;data 01-12-2022 17:35:51
no of lines 7;source ./AXE/TELLIN/2211;data 01-12-2022 17:35:51

But it must show

no of lines 13;source ./AXE/CNA5/LBN/2211;data 01-12-2022 17:35:51 no of lines 7;source ./AXE/TELLIN/2211;data 01-12-2022 17:35:51

How can i fix it?

I read Shell command to sum integers, one per line? but it did not help me . I expecting someone show me how can i change my code

CodePudding user response:

You have a few issues.

First, why bother to test this?

todays_day=$(date  %d) 
if ((todays_day==1)); then
  month="$(date --date='1 day ago'  %y%m)"
else
  month="$(date  %y%m)"
fi

I think all you need is

month="$(date --date='1 day ago'  %y%m)"

which accomplishes the same thing.

Second, your output is inside your loop, which isn't what you want - but since you are using a pipe, your variables will be scoped to the subshell of the loop.
Try this -

month="$(date --date='1 day ago'  %y%m)"
while read catalog 
do sum=0
   while read lines 
   do ((sum =lines))
   done < <( zgrep -ch . "$catalog/*.z" )
   echo "no of lines $sum;source $catalog;data $(date  "%d-%m-%Y %T")"
done < <(find ./ -type d -name "$month" )

Note only one find. If your example output can be trusted for a pattern, we could simplify the outer loop to

for catalog in ./AXE/*/$month

or, if there could be deeper more then one level of subdirectories between,

shopt -s globstar
for catalog in ./AXE/**/$month

which eliminates the need for the find at the end entirely. #!/bin/bash month="$(date --date='1 day ago' %y%m)" # sums previous month on the 1st for catalog in ./AXE//$month # processes each $month dir do sum=0 # reinit sum for each dir while read lines # lines is the count per file do ((sum =lines)) # sum the files in the dir done < <( zgrep -ch . "$catalog/.z" ) # zgrep is your friend echo "no of lines $sum;source $catalog;data $(date "%d-%m-%Y %T")" done

CodePudding user response:

I try to do like these, but it doesn't work

month="$(date --date='1 day ago'  %y%m)"
while read catalog 
do
    sum=0
    while read lines 
    do ((sum =lines))
    echo $lines
    done < <( zgrep -ch . "$catalog")
    echo "no of lines $sum;source $catalog;data $(date  "%d-%m-%Y %T")"
done < <(find $(find ./ -type d -name "$month" ) -type f -name "*.z")

it shows

13
no of lines 13;source ./AXE/CNA5/LBN/2212/3.z;data 02-12-2022 13:45:33
13
no of lines 13;source ./AXE/CNA5/LBN/2212/33.z;data 02-12-2022 13:45:34
13
no of lines 13;source ./AXE/CNA5/LBN/2212/333.z;data 02-12-2022 13:45:34
14
no of lines 14;source ./AXE/CNA5/LBN/2212/4.z;data 02-12-2022 13:45:35
13
no of lines 13;source ./AXE/TELLIN/2212/33.z;data 02-12-2022 13:45:36
14
no of lines 14;source ./AXE/TELLIN/2212/4.z;data 02-12-2022 13:45:36

  • Related