awk 从文件中获取所需数据并逐列打印

awk 从文件中获取所需数据并逐列打印

我有一个如下所示的文本文件。

mark     10 20 30
lawrence 40 22 60
mark     11 12 13
mike     15 16 17
lawrence 21 22 23
mike     31 32 33
mike     41 42 47

我想处理它并产生符合这些条件的输出:

  • 每个唯一名称一行(第一列)。因此,对于上面的例子,应该有三个输出线; “马克”、“劳伦斯”和“迈克”各一个。
  • 输出表面上看起来与输入类似:
    • 四列。
    • 输出的第一列是名称(输入的第一列)。
    • 第二、第三和第四列是整数。
  • 第二列是该名称在第一列中出现的次数。
  • 第三列是名称在第一列中出现的次数,且输入的第三列中的值为 20。
  • 第四列是名称在第一列中出现的次数,而输入的第三列中的值为 22。

预期输出:

mark     2  1  0
mike     3  0  0
lawrence 2  0  2

我写过

... | awk '{ c[$1]++ } END { for (name in c) print name, c[name] }'

我的代码只输出

mark     2 
mike     3 
lawrence 2 

答案1

awk '
    {name[$1]++}      #Counts how many times each name appear
    $3==20{x20[$1]++} #Counts how many times 20 appears in third column
    $3==22{x22[$1]++} #Counts how many times 22 appears in third column
    END{
        for (i in name){
            printf "%s %d %d %d\n",i,name[i],x20[i],x22[i]
        }
    }
' file

输出:

mike 3 0 0
lawrence 2 0 2
mark 2 1 0

答案2

类似的概念@卡西莫多的回答但在一个地方使用值20and22而不是 3,并且没有将值硬编码到数组的名称中:

awk '
    { namesCnt[$1]++; pairsCnt[$1,$3]++ }
    END {
        for (name in namesCnt) {
            print name, namesCnt[name], pairsCnt[name,20]+0, pairsCnt[name,22]+0
        }
    }
' file

答案3

要将输出排列成列,如问题所示,请采用其他答案之一(卡西莫多的或者 艾德·莫顿的)并将其通过管道传输到column -t.

相关内容