文件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
这里,因为没有第三列。
有关的:
- 我对问题的回答使用 grep 查找不在两个文件中的文本
答案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