【问题标题】:awk - how two scripts interact with each other?awk - 两个脚本如何相互交互?
【发布时间】:2012-06-04 09:25:53
【问题描述】:

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

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' 或其他系统函数?

【问题讨论】:

  • nanshi,我不清楚你到底想要达到什么目的。我已经“找到第 1 列的最大频率”(“3”的六次事件),但是“辅助函数”是什么意思?你想对结果做什么?
  • @ghoti,我的意思是辅助函数是 awk 脚本中的一个函数,用于执行子任务,例如查找第 1 列的最大频率 :)

标签: bash shell awk gawk


【解决方案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) 等于为重置的文件记录号 (FNR)每个新文件。在与此条件相关的块中,计算每个数字出现的次数。 next 语句导致执行循环以从文件中读取下一行。当到达第二个文件时,条件不再成立,将跳过此块。

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

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

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

【讨论】:

  • 这是一个非常详细的解释:)。非常感谢!我会试试这个。同时,你认为 Python 比 awk 更适合执行这样的任务吗?祝你有美好的一天!非常感谢您的帮助:)
【解决方案2】:

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

awk ... | awk ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 2011-10-24
    • 2023-03-04
    • 2015-03-11
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    相关资源
    最近更新 更多