2つのサンプルファイルがあるとしましょう。最初のファイルは、名前の最初の2文字と姓の最後の2文字を組み合わせて作成された一意の従業員名で埋められます。Example : Peter Smith - Peht
最初のファイルには以下が含まれます。
Peht
Mawo
Stso
Makr
Bavo
2番目のファイルには、システムにログインした時間の履歴が含まれています。 (明らかにリストにないスタッフもいますfile1
。)
2番目のファイル:
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
。可能であれば、誰かが私にこの問題を解決するための優雅な解決策を与えることができますか?file2
grep
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 stringは、行の先頭(^)にユーザー名を固定し、行の後にスペースを強制することを意味します。
答え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)
デフォルトでは、名前をUE名file1
にuniq
関連付けて、file2
使用0
中の不足しているフィールドに基づいて計算しますfile2
。
私はawk
次を実行します:
awk 'NR==FNR{s[$1]++;next}
{if ($1 in s) {print $1, s[$1]}
else {print $1, 0}}' file2 file1
まず read を実行しfile2
、各名前の発生回数を数え、次にfile1
各名前の個数を読み込んで印刷しますfile2
(またはfile2
名前がその名前にない場合は 0 を印刷します)。