在 bash 中使用 for 循环变量执行其他命令

在 bash 中使用 for 循环变量执行其他命令

我想运行一个 for 循环,它计算以下任务:运行awk10 次,求和输出并打印最终结果。代码附在下面:

sum=0
for i in {1..10}
  do
  count=`awk '{if ($NF==$i) {print $NF}}' * | wc -l`
  sum=$[sum+count]
  echo $sum
done

问题是,如果我更改$NF==$i$NF==1,那么结果是正确的,但我想使用 for 循环运行 10 次。

代码中存在什么问题?

答案1

在以下位置完成整个事情会更有效awk

awk -v n=0 '
  {for (i = 1; i <= 10; i++) if ($NF == i) {n++; break}}
  END {print n}' ./*

或者如果最后一个字段始终是整数:

awk -v n=0 '
  $NF >= 1 && $NF <= 10 {n++}
  END {print n}' ./*

或者,如果您希望比较是词法的,并且只允许这些数字的1, 2, 3...,10表示(而不是01, 1e0, 1.0...):

awk -v n=0 '
  $NF ~ /^([123456789]|10)$/ {n++}
  END {print n}' ./*

答案2

这里的问题是您试图在单引号内进行 shell 变量扩展' ... '。但是,在单引号内,变量扩展被暂停(参见例如这个答案这里或Lhunath 和 GreyCat 的 Bash 指南),这就是为什么实际上建议这样做的原因:因为$在取消引用各个输入字段时执行类似的功能awk(但字段编号也可以由变量名表示,如在例如中$NF),将程序封装在单个输入字段中引号避免了并发的“变量扩展”。

awk在您的情况下,您可以使用以下命令将值“导入”到程序中

awk -v fieldnr="$i" '{if ($NF==fieldnr) {print $NF}}'

尽管如此,您的问题似乎可以在 中完全解决awk,所以也许您想更详细地解释您想要完成的任务,我们可以尝试找到一种更优雅(并且可能更快)的方法;不过,提出另一个问题可能是合理的......

答案3

如果您的脚本按照我的想法执行(即sum从 1 循环到 10 时打印匹配行的增量值),那么您真正需要生成 shell 脚本将生成的输出的是:

awk '
{ counts[$NF]++ }
END {
    for (i=1; i<=10; i++) {
        sum += counts[i]
        print sum
    }
}
' *

上面的内容未经测试,因为您没有提供任何示例输入/输出来进行测试。

答案4

#!/bin/bash
# Tested with -- GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
set -e

for i in `seq 1 1000`
do
  echo $i
  # Run your command here
done

相关内容