我如何 return 每个名称在文件中出现的次数? [命令行]

How do I return the number of times each name appears in a file? [Command Line]

给定一个包含未指定数量名称的文件,我如何在不知道正在搜索的名称的情况下计算每个名称在文件中出现的次数?

是的,逗号之间笨拙的名称间距是文件标准预期格式的一部分。

Sample_Names.txt :

Adam, Bob ,Billy, Cassandra ,Cally , Catherine, George
Amanda, Bob , Cassandra , Harry, Julie
Adam, Bob ,Billy, Harry, Larry

我目前在这个配置下执行命令:

awk -F , '{for(i=1; i <= NF; i++) grep $i | wc -l;}' Sample_Names.txt

这return秒:

awk: line 1: syntax error at or near wc

命令或 Shell 脚本的成功执行应该 return 一个如下所示的文件:

Adam 2
Amanda 1
Billy 2
 Bob  3
Cally  1
 Cassandra  2
 Catherine 1
 George 1
 Harry 2
 Julie 1
 Larry 1

或类似的东西

使用 GNU 实用程序:

tr -s ',' '\n' < example.txt | sed 's/^[ ]*//; s/[ ]*$//' | sort | uniq -c
   2 Adam
   1 Amanda
   2 Billy
   3 Bob
   1 Cally
   2 Cassandra
   1 Catherine
   1 George
   2 Harry
   1 Julie
   1 Larry

解释:

tr -s ',' '\n' < example.txt <- 用换行符替换所有逗号

sed 's/^[ ]*//; s/[ ]*$//' <- 删除每个名称前后的所有空格

sort | uniq -c <- 对名称进行排序,然后计算每个名称的出现次数

--

如果需要,您还可以使用 awk 对输出重新排序,例如

tr -s ',' '\n' < example.txt | sed 's/^[ ]*//; s/[ ]*$//' | sort | uniq -c | awk '{print , }'
Adam 2
Amanda 1
Billy 2
Bob 3
Cally 1
Cassandra 2
Catherine 1
George 1
Harry 2
Julie 1
Larry 1

我认为您不需要为此使用 awk,请尝试将 -o directive 添加到 for 循环中的 grep 命令。那应该找到每个字符串匹配项并每行输出匹配项 1,wc 可以轻松处理。

使用 awk,-F , 将字段分隔符单独设置为逗号,但您仍然需要空格。

如果你想从 awk 运行 shell 命令,你需要 system().

但这不是必需的,您可以使用纯 awk:

awk -F '[[:space:],]+' '
{
     for (i=1; i<=NF; i++) {
         names[$i]++
     }
}
END {
    for (i in names) {
        print names[i]"\t"i
    }
}'

您可以将其通过管道传输到 sort -rnk 1,1 以按频率排序。

如果你有grep -o,还有:

grep -Eo '[[:alpha:]]+' | sort | uniq -c | sort -rn -k1,1

在某些地区(例如 LC_ALL=POSIXLANG=C),这不适用于 ü 等非 ascii 字符。它将拆分这些字符的名称。

您可以改为使用定界符进行拆分,例如 awk,这样更灵活:

grep -Eo '[^[:space:],]+' | sort | uniq -c | sort -rn -k1,1