如何在下面的示例中使用awk命令来存储值?

如何在下面的示例中使用awk命令来存储值?,awk,Awk,我想根据以下文件中位置67的值,即D,从位置68求和到81: 10010001602171813800899901000000000101211000002007-05-130005316347D000000000000800 000000002007-05-18x?0000000000 10010001602171813800899901000000000201211000002007-05-130748402438C000000000000800 000000002007-05-18x?00

我想根据以下文件中位置67的值,即
D
,从位置68求和到81:

10010001602171813800899901000000000101211000002007-05-130005316347D000000000000800 000000002007-05-18x?0000000000
10010001602171813800899901000000000201211000002007-05-130748402438C000000000000800 000000002007-05-18x?0000000000
10010001602171813800899901100000000101211000002007-05-130005316347D000000000000800 000000002007-05-18x?0000000000
10010001602171813800899901100000000201211000002007-05-130748402438C000000000000800 000000002007-05-18x?0000000000
我想根据第67位的值,得到从第68位到第81位的另一个和,即
C
,即

s1 =1600 (based on D)
s2 =1600 (based on C)
我曾经

grep "^1" file.txt | \
  awk '{s[substr($0,67,68-67)]+=substr($0,68,83-68)} 
       END { for (i in s) { print i, s[i] }}'
得到的总数是

C 1596678
D 1596678
但是我想将上述两个值存储在两个单独的变量中,比如A应该保存1596678,B应该保存1596678。

编辑:,因为OP告诉
mapfile
不起作用,所以在这里放置另一个命令

numbers=$(grep "^1" | awk '{array[substr($0,67,1)]+=substr($0,68,15)+0} END{for(i in array){print i,array[i]}}')
for (( i=0; i<${#numbers[@]}; i++ )); do echo ${numbers[i]}; done
现在,如果您想查看数组的单个值,可以执行以下操作:

echo "${array1[1]}"
D 160


注意:如果数组中有来自
awk
的更多值,则不需要使用太多变量,因为数组应该处理它。另外,如果您只需要整数值,那么在上述代码中也将从
{print i,array[i]
更改为
{print array[i]

因此..首先,数组元素是独立的变量。在awk脚本的结束块中的任何点,您都可以执行以下操作:

A=s["C"]
B=s["D"]
但如果不知道您的输入数据仅限于第67列中的这两个字符,您就无法知道要分配多少变量。一般来说,编写代码以灵活地处理不同的输入数据,而不是假设您的数据始终具有特定的内容,这不是一个好主意。即“C”或“D”是数据的一部分,而不是架构

也就是说…在你原来的awk中修正数学,我想到了:

$ awk -v n=67 '
/^1/ {
  s[substr($0,n,1)]+=substr($0,n+1,15)
}
END {
  for(i in s) printf "%s %d\n",i,s[i]
}
' input.txt
这里的想法是,
n
是我们开始关注数据的地方(即,它提供了数组的键),下面15个字符是要求和的数字

或者,如果您的
awk
实际上是
gawk
,那么将FIELDWIDTHS变量用于固定宽度字段可能更清晰:

$ gawk '
BEGIN{
  FIELDWIDTHS="66 1 15 1"
}
/^1/ {
  s[$2]+=$3
}
END {
  for(i in s) printf "%s %d\n",i,s[i]
}
' input.txt
使用您提供的输入数据,这两种情况都会导致:

C 1600
D 1600

请注意,我将使用与您的结果相匹配的解决方案(即每个$3的值为
800
),而不是您的问题(它们的值为
8
)。请根据需要根据实际字段宽度随意调整此解决方案。

类似于
read-r\a\b的内容它给出变量$a的输出,而$b的输出为空。因此,我可以删除打印语句吗?为什么您不能创建一个示例,其中第3列为D,您希望对第5列到第8列或类似列求和?请参阅和ar关于创建一个(在本例中强调最小值)的部分。当您使用awk时,您不需要grep。
grep“^1”文件| awk'{foo}'
与调用:
awk'/^1/{foo}文件相同。
我得到一个-ksh:mapfile:找不到[没有这样的文件或目录]@user9794957,它对我很好,哪个操作系统对你很好?另外
mapfile
手册页显示它是bash实用程序,所以它应该在那里。请告诉我同样的情况。@user9794957,只有
awk
grep
对你很好?没有
操作系统是linuxit给我C 1596678 D 1596678吗
$ gawk '
BEGIN{
  FIELDWIDTHS="66 1 15 1"
}
/^1/ {
  s[$2]+=$3
}
END {
  for(i in s) printf "%s %d\n",i,s[i]
}
' input.txt
C 1600
D 1600