文件1:
91 23 56 44 87 77
99 34 56 22 22 95
41 88 26 79 60 27
95 55 66 69 92 25
文件2:
pass fail pass pass pass fail
pass fail pass fail fail pass
pass pass fail pass pass fail
pass pass fail pass pass fail
由于我想总结每行的总失败标记,因此这是预期的输出。
输出:
100
78
53
91
我想问一下,如何根据file2中的“fail”一词对file1进行过滤,以获得fail标记的总和。
答案1
我会使用矩阵语言来完成这样的任务,例如 GNU Octave。
假设您将通过/失败文件转换为数值,例如:
sed 's/pass/1/g; s/fail/0/g' passfail > passfail.nums
您现在可以执行以下操作:
marks = dlmread('marks');
passfail = dlmread('passfail.nums');
for i = 1:size(marks)(1)
sum(marks(i,:)(passfail(i,:) == 0))
end
输出:
ans = 100
ans = 78
ans = 53
ans = 91
答案2
虽然我认为使用awk
有利于可移植性,但其他语言似乎更容易编写和阅读此任务。提到了 GNU Octave,但大多数机器上并未预安装。另一方面,大多数系统都预装了 python 版本。这是一个Python版本:
for marks, decisions in zip(open('file1').readlines(), open('file2').readlines()):
row_score = 0
for mark, decision in zip(marks.split(), decisions.split()):
if decision == 'fail':
row_score += int(mark)
print(row_score)
它返回您期望的输出。
答案3
这是我的awk
方法:
awk 'NR==FNR{for(i=1;i<=NF;i++) a[NR"-"i]=$i; next} \
{for(j=1;j<=NF;j++) if($j=="fail") b[FNR]+=a[FNR"-"j]} \
END{for(k in b) print b[k]}' file1 file2
awk 不支持二维数组,因此我们通过在同一数组索引中组合两个数字(行和字段)来组合二维数组。输出是:
100
78
53
91
答案4
awk '
BEGIN{ pf=ARGV[2]; ARGV[2]="" }
{ getline l <pf; split(l, a); n=0;
for(i=1;i<=NF;i++) if(a[i]=="fail") n+=$i;
print n }
' file1 file2
100
78
53
91
就像 @Maxim 的 python 版本一样,但与所有其他答案不同,这是并行处理两个文件,逐行,而不是将其中一个整个加载到内存中。