awk - 两个脚本如何相互交互?

时间:2012-06-03 23:25:14

标签: bash shell awk gawk

我没有找到关于这个主题的任何明确的教程。假设我有一个输入文件:

1 abc
1 def
1 ghi
1 lalala
1 heyhey
2 ahb
2 bbh
3 chch
3 chchch
3 oiohho
3 nonon
3 halal
3 whatever

说我想先找到第一列出现的最大数量,即出现6次的“3”。然后我需要将这个数字(即6)提供给另一个脚本来通过文件进行一些计算。有什么方法可以做到这一点?

基本上,我想知道是否可以编写一个函数来遍历文件,然后在调用辅助函数的main函数中找到“max”。另外,我想知道是否可以在辅助函数中执行$(...)来调用'awk'或其他系统函数?

2 个答案:

答案 0 :(得分:1)

awk 'NR == FNR {nums[$1]++; next} ! flag {flag = 1; for (num in nums) {if (nums[i] > max) {max = nums[i]}}} {print max * $3}' filetomax filetoprocess

这里分为多行:

awk '
    NR == FNR {
        nums[$1]++;
        next
    } 
    ! flag {
        flag = 1; 
        for (num in nums) {
            if (nums[i] > max) {
                max = nums[i]
            }
        }
    } 
    {
        print max * $3
    }
' filetomax filetoprocess

在这里,我们正在执行相同的操作,以查找您seen before的最大数字。我们使用的技术经常用于处理一个文件而不是另一个文件,而不是使用主块和END块。 NR == FNR条件仅在读取第一个文件时为真,因为对于所有文件中的每一行递增的记录号(NR)总共等于文件记录号({{1} })为每个新文件重置。在与此条件关联的块中,计算每个数字出现的时间。 FNR语句导致执行循环以从文件中读取下一行。到达第二个文件时,条件不再为真,并且将跳过此块。

下一个条件(next)检查变量的内容是否为真。由于它尚未设置,因此它是错误的。感叹号否定了条件,因此此时执行进入此块。现在设置了标志,以便下次检查条件时,将跳过此块。 ! flag循环会检查哪个号码出现次数最多,就像我对您的其他问题的回答一样。

现在,可以以您喜欢的任何方式处理第二个文件,并且在此处理期间可以使用变量for。我只是使用max语句来说明这一点。您仍然可以像往常一样使用块选择器条件,包括一个或多个print块。我没有显示END块,但您可以在此脚本的顶部添加一个块以进行所需的初始化。请注意,可以使用BEGINBEGIN块中处理第一个文件。这只是另一种完成同样事情的技术。

文件名按照要处理的顺序列出。用于在I&#39中查找最大计数的文件称为" filetomax"。第二个文件用于对I' ve进行主要处理,称为#34; filetoprocess"。

答案 1 :(得分:0)

我们使用管道。它接受第一个进程的stdout并将其连接到第二个进程的stdin。

awk ... | awk ...