read non-constant number of files in bash (multiple files in bash)

read non-constant number of files in bash (multiple files in bash)

我有数量未知的 log/text 个文件,我需要使用 Bash 脚本从中读取并对其中的一些变量求和。 问题是我的变量在循环中的每次迭代后重置。 我看到了 ,但是有一定数量的文件(只有两个文件)。

我用 ls 找到了文件的数量。 我使用 cat 从每个文件中读取。 我无法正确保存和添加变量。 这是我尝试做的:

logfiles=($(ls -l ~ | grep -o '[^ ]+$' | grep ${LOG_NAME}log))
num_of_logs=${#logfiles[@]}
for LOG_NUM in `seq 0 $(($num_of_logs-1))`
    do (
         SPEED=`cat $LOG | grep sum_sent -A7 | grep bits_per_second | tr "," " " | awk '{ SUM+=$NF } END { print SUM } '`
         BITS=$(printf '%.0f' ${SPEED})
         GIGABITS=$( bc -l <<< "scale=2; $BITS/1000000000" )
         GIGASUM=$( echo "$GIGABITS+$GIGASUM" | bc )
        )
    done `

试过: 将“cat”命令分隔成一个带有数组的单独循环,并将每个结果输入到不同的索引。 产生了相同的结果,数组也为空。

The problem is my variables reset after each iteration in a loop.

是的,因为您将循环体括在括号 () 中。 subshell 中 运行 内的所有内容,特别是其中的变量定义和更改仅影响 subshell,这在每次迭代中都是新的。如果您希望所有内容都 运行 在同一个 shell 中,则只需省略这些即可。

此外,

  • 您没有为变量 GIGASUM 设置初始值,因此它最初为空(不是 0)。

  • 你在最后一行的末尾有一个反引号 (`)。

  • $() 替代方法比反引号更具可读性。由于您已经假设 shell 支持该形式,因此您应该始终如一地使用它。

  • 如果变量的值不完全在您的控制之下,通常即使它们完全在您的控制之下,也应该引用其值的扩展。

  • 您不应尝试解析 ls 的输出。通配符有时就足够了, find 服务更普遍。特殊情况下与stat命令结合使用。解析 ls -l 的输出以删除普通 ls 没有的所有内容尤其没有意义。

  • 你从未设置变量LOG

  • 不清楚为什么要遍历日志数量而不是直接遍历日志文件名。

  • 当您可以通过名称将文件指定给第二个命令时,不要 cat 将文件添加到另一个命令中。

  • 使用空格和换行符使您的代码更清晰。有几个地方您可以自然地换行,而无需转义换行符。

我相信还有更多可用的改进,但这涵盖了以上所有内容:

# Supposing that you actually need the logfiles array for something later,
# after the loop (otherwise, you can put the glob directly into the `for` command):
logfiles=(~/*"${LOG_NAME}"log*)

GIGASUM=0
for LOG in "${logfiles[@]}"; do
    SPEED=$(grep sum_sent -A7 "$LOG" |
      grep bits_per_second |
      tr "," " " |
      awk '{ SUM+=$NF } END { print SUM } ')
    BITS=$(printf '%.0f' ${SPEED})
    GIGABITS=$( bc -l <<< "scale=2; $BITS/1000000000" )
    GIGASUM=$( echo "$GIGABITS+$GIGASUM" | bc )
done