计算一个文件中的模式在另一个文件中出现次数的优雅方法

计算一个文件中的模式在另一个文件中出现次数的优雅方法

假设我们有两个示例文件。第一个文件填充了通过组合名字的前两个字符和姓氏的最后 2 个字符创建的唯一员工姓名。Example : Peter Smith - Peht

第一个文件包含:

Peht
Mawo
Stso
Makr
Bavo

第二个文件包含他们登录系统时的记录。 (显然还有未列出的员工file1。)

第二个文件:

Mawo 21.4.2016 17:49
Peht 21.4.2016 17:58
Mawo 22.4.2016 7:58
Wato 22.4.2016 7:59
Stso 22.4.2016 8:02
Bavo 22.4.2016 8:15
Bane 22.4.2016 9:01
Bavo 23.4.2016 9:12
Mawo 23.4.2016 9:24
Dalo 23.4.2016 9:54
Peht 23.4.2016 9:58
Grma 24.4.2016 10:00

我需要找出 file1 中的员工连接到系统的次数 ( file2)。

最好的方法是什么?我想到的唯一解决方案是进行一些 2 个循环,对于file1循环整个file2thengrep名称中的每个名称,询问名称是否匹配(如果是则那么)count++。任何人都可以给我一些优雅的解决方案来解决这个问题,例如awk如果可能的话?

答案1

一些简单的事情,比如:

mapfile -t names < file1
for name in "${names[@]}"
do
  echo "${name}" $(grep -c "^$name " file2)
done

将提供如下输出:

Peht 2
Mawo 3
Stso 1
Makr 0
Bavo 2

grep 字符串表示将用户名锚定在行的开头 (^),并在行后强制添加尾随空格。

答案2

测试.awk:

FNR == NR{ 
  names[$1]
  next
}   
($1 in names){
  ulog[$1]++
}   
END{
  for(name in ulog){
    print name ":" ulog[name]
  }   
}   

并将其运行为 awk -f test.awk user.list user.log

FNR==NR # 文件记录号==记录号,如果是那么我们仍然在第一个文件

next # 因为我们仍在第一个文件中,所以跳过其余部分并拉入下一行

其余的应该是不言自明的

或作为单行

awk 'FNR == NR{ names[$1]; next } ($1 in names){ ulog[$1]++ } END{ for(name in ulog){ print name ":" ulog[name] } }' user.list user.log

答案3

这是 // 的另join一种sort方式uniq

join  -1 1 -2 2 -a1 -e "0" -o 1.1 2.1 <(sort file1) \
<(cut -d' ' -f1 file2 | sort | uniq -c)

基本上,它将名称file1unique 名称连接起来,并根据file2使用0中缺少的字段进行计数file2


awk会运行:

awk 'NR==FNR{s[$1]++;next}
{if ($1 in s) {print $1, s[$1]}
else {print $1, 0}}' file2 file1

首先读取file2,计算每个名称出现的次数,然后读取file1并为每个名称打印计数file2(如果名称不在其中,则file2打印 0)。

相关内容