Bash脚本-如何对循环的输出进行求和和聚合,而



我写了一个脚本来计算每个文件的行数:

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

现在它累加行数并显示在结果

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

但是必须显示

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

我该如何修复它?

我读Shell命令来对整数求和,每行一个?但这对我没有帮助。我期待有人告诉我如何改变我的代码

你有几个问题。

首先,为什么要测试这个呢?

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

我认为你所需要的是

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

完成同样的事情。

第二,你的输出在你的循环中,这不是你想要的——但是因为你使用的是管道,你的变量将被限定在循环的子shell中。
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" )

只注意一个find。如果您的示例输出对于模式是可信的,我们可以将外部循环简化为

for catalog in ./AXE/*/"$month"

或者,如果在子目录之间有一层以上的目录,

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

,它完全消除了对结尾的find的需要。

#!/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 
<标题>

编辑正如我上面所说的,

或者,如果在子目录之间有一层以上的子目录,

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

代入

#!/bin/bash
shopt -s globstar                          # allow ** for arbitrary depth
month="$(date --date='1 day ago' +%y%m)"   # sums previous month on the 1st
for catalog in ./AXE/**/"$month"/          # / at the end gets dirs only
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 ) # / is part of $catalog
echo "no of lines $sum;source $catalog;data $(date +"%d-%m-%Y %T")"
done 

上面的外部循环选择适用的目录;内循环计算中每个文件中的记录,并按目录求和,这是我认为您想要的。

在你编辑过的代码的回答帖子中,你已经改变了外部循环来直接表示每个单独的文件,所以内部循环只读取一行,没有什么要求和的,所以不需要内部循环,但是不需要按目录求和。

您是想要每个文件、每个目录还是其他东西的总数?

<标题>

更新道歉。我将*.zglob包含在引号内。上述修正。

如果在任何路径名中没有像空格这样的调皮字符,你可以完全去掉引号,但我倾向于不做这样的假设-它会让你感到惊讶。

最新更新