【问题标题】:how shell script merging three files by lines and calculating some value, meeting some conditionshell脚本如何按行合并三个文件并计算一些值,满足一些条件
【发布时间】:2016-03-30 06:54:22
【问题描述】:
while read line1
do
    while read line2
    do
        while read line3 
        do  echo "$line1, $line2, $line3" | awk -F , ' $1==$5 && $6==$11 && $10==$12 {print $1,",",$2,",",$3,",",$4,",",$6,",",$7,",",$8,",",$9,",",$10,",",$13,",",$14,",",$15}' >>out.txt
    done < grades.csv
    done < subjects.csv
done < students.csv

在此代码中,我按行(叉积)合并三个文件,如果任何合并的行满足条件“$1==$5 && $6==$11 && $10==$12”,我将在输出文件中打印它们. 现在我的问题是,如果满足条件,我想继续为每次迭代添加“$13”字段值。

我该怎么做?请帮忙。 这是示例文件。

gardes.csv 包含行:

1,ARCH,1,90,very good,80   
1,ARCH,2,70,good,85    
1,PLNG,1,89,very good,85

subjects.csv 包含行:

1,ARCH,Computer Architecture,A,K.Gose   
1,PLNG,Programming Languages,A,P.Yang    
1,OS,Operating System,B,K.Gopalan    
2,ARCH,Computer Architecture,A,K.Gose

students.csv 包含行:

1,pankaj,vestal,986-654-32   
2,satadisha,binghamton,879-876-54    
5,pankaj,vestal,986-654-32    
6,pankaj,vestal,986-654-31

这是预期的输出:

ARCH  1  pankaj     vestal      986-654-32  Computer Architecture  A  K.Gose  1  1  90  very good  80
ARCH  1  pankaj     vestal      986-654-32  Computer Architecture  A  K.Gose  1  2  70  good       85
ARCH  2  satadisha  binghamton  879-876-54  Computer Architecture  A  K.Gose  1  1  90  very good  80
ARCH  2  satadisha  binghamton  879-876-54  Computer Architecture  A  K.Gose  1  2  70  good       85
PLNG  1  pankaj     vestal      986-654-32  Programming Languages  A  P.Yang  1  1  89  very good  85

我还需要另一个可以写入文件的 shell 变量中的 (90+70+90+70+89) 的总和。

【问题讨论】:

  • @fedorqui 和@Ryan 希望添加的完整代码和输入文件能帮助您帮助我。谢谢
  • csv 文件很危险。当您有一个带有, 的字段时,代码将中断。 7,ARCH,1,90,"very, very good",80 或学生 5,Louis,"Paris, France",986-654-32 怎么样?
  • @Walter,是的,但根据我的要求,我将在其中包含不带逗号的字段。逗号只是分隔符。

标签: shell awk


【解决方案1】:

您可以使用join 来创建您的扩展数据并使用awk 对其进行操作。

$ join -t, -1 5 -2 2 <(join -t, -j 1 file3 file2 | sort -t, -k5,5) file1 | column -s, -t

ARCH  1  pankaj     vestal      986-654-32  Computer Architecture  A  K.Gose  1  1  90  very good  80
ARCH  1  pankaj     vestal      986-654-32  Computer Architecture  A  K.Gose  1  2  70  good       85
ARCH  2  satadisha  binghamton  879-876-54  Computer Architecture  A  K.Gose  1  1  90  very good  80
ARCH  2  satadisha  binghamton  879-876-54  Computer Architecture  A  K.Gose  1  2  70  good       85
PLNG  1  pankaj     vestal      986-654-32  Programming Languages  A  P.Yang  1  1  89  very good  85

或者,您也可以在 awk 中进行连接,消除 while 循环。

如果要添加 $11 中的值。

$ join -t, -1 5 -2 2 <(join -t, -j 1 file3 file2 
    | sort -t, -k5,5) file1 | awk -F, '{sum+=$11} END{print sum}'

将结果分配给 shell 变量

$ sum=$(join ... )

【讨论】:

  • 这部分也适用于我的 while 循环代码。我需要一种方法来计算同一循环中第 11 列中所有值的总和。我的意思是我不想单独读取 o/p 文件进行计算。
【解决方案2】:

假设您已加入列以形成 TSV(制表符分隔值)文件或流,并且列 $k1、$k2 和 $k3(在该文件或流中)形成键,并且您想要要对连接中的 $s 列求和,这里是 awk 命令,您可以使用它来形成键和求和的 TSV 列表:

awk -F\\t -v k1=$k1 -v k2=$k2 -v k3=$k3 '
  BEGIN{t=OFS="\t"}
  { key=$k1 t $k2 t $k3; sum[key]+=$s }
  END {for (key in sum) {print key, sum[key] } }'

(使用 awk 处理可能包含逗号的 CSV 文件是自找麻烦,所以我已经说明了如何将 awk 与制表符一起使用。)

【讨论】:

    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    相关资源
    最近更新 更多