1

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

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)提供给另一个脚本以通过文件进行一些计算。有什么方法可以做到这一点?

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

4

2 回答 2

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

在这里,我们正在执行相同的操作来查找您之前见过的最大数字。我们不是使用主块和END块,而是使用一种通常用于处理一个文件然后处理另一个文件的技术。该NR == FNR条件仅在读取第一个文件时为真,因为NR在所有文件中为每一行增加的记录号 ( ) 共同等于FNR为每个新文件重置的文件记录号 ( )。在与此条件相关的块中,计算每个数字出现的次数。该next语句导致执行循环以从文件中读取下一行。当到达第二个文件时,条件不再为真,将跳过此块。

下一个条件 ( ! flag) 检查变量的内容是否为真。因为没有设置,所以是假的。感叹号否定条件,因此此时执行移至该块。现在设置了标志,因此下次检查条件时,将跳过此块。循环检查哪个数字出现的for次数最多,就像我对您的另一个问题的回答一样。

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

文件名按它们要处理的顺序列出。找到最大计数的文件我称为“filetomax”。对我进行主要处理的第二个文件称为“filetoprocess”。

于 2012-06-04T01:25:53.390 回答
0

我们为此使用管道。它获取第一个进程的标准输出并将其连接到第二个进程的标准输入。

awk ... | awk ...
于 2012-06-03T23:36:47.353 回答