有两个文件,如果第一个文件的第 1 列与其他文件的第 1 列值匹配,则添加值并写入新文件

有两个文件,如果第一个文件的第 1 列与其他文件的第 1 列值匹配,则添加值并写入新文件

文件1

Name    marks
sagat    20
raji     30
kamal    56
sanj     10

文件2

Name    marks
sagat    20
kamal    56
Jagan    30
suraj    90
sanj     78

输出文件1(通用名)

Name    marks
sagat    40
kamal    112
sanj     88

输出文件2

Name    marks
raji     30
Jagan    30
suraj    90

答案1

假设 shell 支持进程替换(如bash):

$ join <( sort file1 ) <( sort file2 ) | awk 'BEGIN { OFS="\t"; print "Name", "Marks" } !/^Name/ { print $1, $2 + $3 }'
Name    Marks
kamal   112
sagat   40
sanj    88

join命令将第一列(名称)上的两个(已排序)文件连接起来,并输出出现在两个都文件以及每个文件的标记作为第二列和第三列。这个三列数据被输入一个短awk程序,该程序输出标题,然后简单地打印名称以及第二列和第三列的总和(避免处理任何以 开头的行Name,即旧标题)。

$ join -v1 -v2 <( sort file1 ) <( sort file2 ) | awk 'BEGIN { OFS="\t"; print "Name", "Marks" } !/^Name/ { print $1, $2 + $3 }'
Name    Marks
Jagan   30
raji    30
suraj   90

这做了类似的事情,但现在输出join两个文件中唯一的名称,该文件的标记作为第二列。为了简单起见,该awk程序是相同的,但$2 + $3可以缩短到$2这里,因为没有第三列。

有关的:

答案2

大概是这样的:

#!/bin/sh

I1=./InputFile1
I2=./InputFile2
O1=./OutputFile1
O2=./OutputFile2

rm $O1 $O2
awk 'NR>1{print $1" "$2}' $I1 | while read id mark
    do
        if grep "^$id[ \t]" $I2 >/dev/null; then
            add=`awk "/^$id[ \t]/{print \\$2}" $I2`
            echo $id $(expr $mark + $add) >>$O1
        fi
    done
(
    awk 'NR>1{print $1" "$2}' $I1
    awk 'NR>1{print $1" "$2}' $I2
) | sort -u | while read id mark
    do
        if ! grep "^id[ \t]" $O1 >/dev/null; then
            echo $id $mark >>$O2
        fi
    done

答案3

替代awk

awk -v f="mark.txt" '{
    if (FNR==1) {nof+=1; printf ( "%s\t%s\n", $1, $2) > nof"."f}
        else {marks[$1]+=$2; howManyResults[$1]+=1}
    } END {for (name in marks) printf ("%s\t%s\n", name, marks[name]) >>howManyResults[name]"."f
}' file1 file2

输出

1.标记.txt

Name    marks
Jagan   30
suraj   90
raji    30

2.标记.txt

Name    marks
sanj    88
kamal   112
sagat   40

答案4

接下来是创建上述输出文件的 awk 脚本

#!/usr/bin/gawk -f    
BEGIN        { OFS="\t";          }

NR==1        { print > "out1"; print > "out2" }
FNR==1       { next }
$1 in stud   { print $1,$2+stud[$1] > "out1"; delete stud[$1]; next }
NF == 2      { stud[$1]=$2;  next }

END          { for(i in stud) print i, stud[i] > "out2" }

进而:

$ chmod 755 procfs
$ procfs f1 f2

相关内容