如何通过读取shell脚本中的csv文件来将2列的总和添加到新列中

Posted

技术标签:

【中文标题】如何通过读取shell脚本中的csv文件来将2列的总和添加到新列中【英文标题】:how to do the sum of 2 columns adding that into new column by reading the csv file in shell script 【发布时间】:2021-12-21 07:32:36 【问题描述】:

我正在尝试实现 shell 脚本来读取 csv 文件并对 2 列求和并添加到名为 total 的新列中。但它没有成功完成。请建议我如何实现这一目标。

我的输入 csv 文件

a,b,c
1,2,3
4,5,6

预期输出

a,b,c,total
1,2,3,5
4,5,6,11

这里 a 是主键

我尝试了下面的代码来实现这一点

echo "First arg: 1"
awk "print $3 $2 """""" $1"
echo "First arg: 2
awk -F, "$(NF+1)=Null;1" OFS=, file.csv
awk -F "," "print $1,$2,$3,$2+$3"

我的输出是:

C:\Users\inrenan\NIFI\NIFI-1~1.2-B\NIFI-1~1.2>awk -F "," "print $1,$2,$3,$2+$3" 
a b c 0
1 2 3 5
4 5 6 11

只有我面临的问题是列名

【问题讨论】:

"但是没有成功。"你试过什么没用? @SamBob 请再次检查我更新的问题 主持人:这个问题与当前标记的***.com/questions/62980230/… 不是重复的。这个问题分别对每一行求和,那个问题对所有列求和 【参考方案1】:

这是您需要的 awk 脚本:

BEGIN FS=OFS=","   print $0, (NR==1 ? "total" : $2+$3) 

做任何你必须在 Windows 中使用它的魔法咒语。

在 Unix 中你只需要这样做:

awk 'BEGIN FS=OFS=","   print $0, (NR==1 ? "total" : $2+$3) ' input
a,b,c,total
1,2,3,5
4,5,6,11

但我听说 Windows 有一些最好避免的奇怪引用规则,因此我看到的针对 Windows 的常见建议是将脚本保存在名为 script.awk 的文件中(在 Unix 中也可以这样做)并将其调用为:

awk -f script.awk input
a,b,c,total
1,2,3,5
4,5,6,11

根据您问题中的最后一个脚本,这可能适用于 Windows,但我真的不知道 Windows 引用规则:

awk "BEGIN FS=OFS=\",\"   print $0, (NR==1 ? \"total\" : $2+$3) " input

【讨论】:

【参考方案2】:

使用您展示的示例,请尝试关注awk 程序。这里提到了一个名为fields 的变量awk,其值为2,3,我们可以在其中提到以, 分隔的字段编号,它会处理所有这些字段的总和。

awk -v fields="2,3" '
BEGIN
  FS=OFS=","
  num=split(fields,arr,",")
  for(i=1;i<=num;i++)
    field[arr[i]]
  

FNR==1  print $0,"total"; next 
FNR>1
  sum=0
  for(i=1;i<=NF;i++)
    if(i in field) sum+=$i 
  
  $(NF+1)=sum

1
'  Input_file

【讨论】:

【参考方案3】:

对于非常繁琐的单行:

awk -F',' 'if (NR==1) printf "%s,total\n",$0; else sum=0; for(i=2; i<=NF; i++) sum +=$i; printf "%s,%s\n",$0,sum;' file.csv

【讨论】:

我正在使用.bat 文件编写shell 脚本,我遇到了上述错误,我将' 更改为" 但面临同样的问题 我猜你是在 Windows 中运行的。您确定您正在运行bash 而不是cmd.exe?你用什么运行你的脚本(哪个程序和什么命令)? 是的,我使用.bat格式文件在windows中运行,我更新了我的代码输出,请检查它 “在 Windows 中”来自 cmd?电源外壳? WSL?如果前两个中的任何一个都不是标记的 bash 问题。此解决方案适用于 bash。【参考方案4】:

这是一个获得所需输出的纯批处理文件:

@echo off
setlocal EnableDelayedExpansion

set /P "header=" < input.txt
echo !header!,total
for /f "skip=1 tokens=1-3 delims=," %%a in (input.txt) do (
   set /A "total=%%b+%%c"
   echo %%a,%%b,%%c,!total!
)

【讨论】:

以上是关于如何通过读取shell脚本中的csv文件来将2列的总和添加到新列中的主要内容,如果未能解决你的问题,请参考以下文章

管道输入到脚本中

我想写一个简单的shell脚本,来将我的源文件中的每行进行排序输出,

如何通过将 csv 数据存储在变量中来将其访问到 yml 文件中?

Shell-Script用于连接目录中具有两个键列的所有CSV文件

在Shell脚本中读取CSV文件,直到没有标题的行结束

jmeter能不能随机读取csv文件中的参数?