【问题标题】:awk, compare field with previous line field and conditionally print bothawk,将字段与前一行字段进行比较并有条件地打印两者
【发布时间】:2021-10-29 22:40:21
【问题描述】:

我可以用 python/perl 更轻松地做到这一点,但我想在 awk 方面做得更好,我知道这可以用它来实现,我不是经验丰富的系统管理员,这些是我在生产中的第一个脚本,我会感谢您对此的一些帮助和指点。

我有一个包含如下数据的文件:

第一个字段是缓冲池名称,第二个字段是程序大小,第三个字段是程序名称。

数据文件:

NATBPG 6286 SPAP303
NATBPG 9170 SPAP303N
NATBPG 1754 SPAP303S
NATBPZ 1754 SPAP303S
NATBPZ 9170 SPAP303N
NATBPZ 6286 SPAP303
NATBPB 6700 SPAP303

和另一个包含所有唯一程序名称的文件:

程序:

SPAP303S
SPAP303N
SPAP303

我需要在相同或不同的缓冲池中查找大小不同的所有事件,并且在这种情况下打印出所有程序事件,因此在上述情况下,所需的输出将如下所示:

NATBPZ SPAP303 6286
NATBPB SPAP303 6700
NATBPG SPAP303 6286

到目前为止,我有以下 bash+awk 代码的 sn-p:

while read programs; do
    awk -v program="$programs" '{
        if($3==program && prev!=$2)
        {
            print $1,$3,prev;
        }
        else
        {
            print "ok";
        }
        if($3==program)
        {prev=$2}
        }' datafile >> outputfile
done < programs

产生以下输出

NATBPG SPAP303S 
NATBPG SPAP303N 
NATBPG SPAP303 
NATBPB SPAP303 6286
NATBPG SPAP303S 
NATBPG SPAP303N 
NATBPG SPAP303 
NATBPB SPAP303 6286

经过一些非常难看的清理(让 awk 只打印出带有 NR>2 的行),我得到了一个可以接受的输出,如下所示:

NATBPB SPAP303 6286
NATBPB SPAP303 6286

但我还是错过了这条线

NATBPB SPAP303 6700

所以我有三个问题:

  1. 如何获取我丢失的线路?我尝试了一些组合,在 awk 程序的不同阶段将当前行保存为 $0 并在满足条件时将其打印出来,但我无法让它工作

  2. 为什么我实际上会从我的 awk 程序中得到这个输出?我以为我在打印这个

打印 $1,$3,prev;

只有当两个条件都满足时,否则我会打印出来,而是在我的输出文件中打印以下内容:

NATBPG SPAP303S 
NATBPG SPAP303N 
NATBPG SPAP303 
NATBPB SPAP303 6286

我不知道前三行是从哪里来的

  1. 我知道这种方法是有缺陷的,因为最好使用某种数组来存储程序的出现,同时按程序循环数据程序,然后检查它们是否都具有相同的大小,如果它们没有' t 打印出数组并转到下一个程序,这在 awk 中是否可能?我想是的,但我有点不知所措。

【问题讨论】:

  • while read programs; do ... done &lt; programs 有点混乱。看来while read program; do ... done &lt; programs 会更好。但是你真的想完全避免这个循环并在 awk 中做所有事情。
  • 请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案。

标签: awk


【解决方案1】:

使用 GNU awk:

$ gawk 'NR==FNR{a[$3][$2];next}length(a[$3])>1' file file

输出:

NATBPG 6286 SPAP303
NATBPZ 6286 SPAP303
NATBPB 6700 SPAP303

$ gawk 'NR==FNR {          # first iteration 
    a[$3][$2]              # hash entries
    next
}                          # second iteration
length(a[$3])>1' file file # see if $3 has more than one 2nd dim. entries

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 2015-10-18
    • 2023-03-31
    • 2019-10-08
    • 2015-12-21
    相关资源
    最近更新 更多