Awk数组循环翻译

时间:2016-06-22 07:32:20

标签: loops awk hp-ux

在处理HP UX存储迁移项目时, 我发现awk声明如下:

ioscan -funNCdisk | \
awk '{a[NR]=$0} $0~s {f[NR]++} END {for (j=1;j<=NR;j++) if (f[j]) for (i=j+C;i<=j+C;i++) \
print a[i]}' C=1 s="NetApp"

它似乎打印出与“NetApp”匹配的行以及与该关键字相关的更多行。

有人能帮我理解这句话的含义吗?

谢谢

2 个答案:

答案 0 :(得分:2)

让我们将awk脚本单独分解到一个文件中并调用该文件script.awk

#!/usr/bin/awk -f

BEGIN   { C = 1; s = "pants" }
        { a[NR] = $0 }
$0 ~ s  { f[NR]++ }
END     {
    for (j = 1; j <= NR; j++)
        if (f[j])
            for (i = j + C; i <= j + C; i++)
                print a[i]
}
  1. 我在s块中添加了变量CBEGIN的初始化,只是为了方便测试。您的脚本从命令行获取这些内容。

  2. 在数组a中添加最后一行。

  3. 如果该行包含字符串s(作为正则表达式测试),则在索引处递增数组f  对应于当前行(在这种情况下,这与f[NR] = 1相同)。

  4. 在输入结束时:遍历所有存储的行,如果我们标记了f数组中的行,则打印存储的行,从标记的行加上C开始继续,呃,不,只打印那一行(这里的错误?)。

  5. 因此,我们的脚本将打印与正则表达式s匹配的任何行之后的每一行。

    测试它:

    $ cat data.in
    Hello world!
    My pants
    are on fire!
    No, hold on,
    Those are not *my* pants.
    Phew!
    
    $ chmod +x script.awk
    
    $ ./script.awk data.in
    are on fire!
    Phew!
    

    所以,在你的情况下(在这里用“NetApp”替换“裤子”),它实际上与(使用GNU sed

    相同
    sed -n '/pants/,+1p' data.in | grep -v 'pants'
    

    grep -A1 'pants' data.in | grep -E -v 'pants|-'
    

    个人注释:这就是我讨厌所谓的“单行”的原因。它们很难看,没有人理解它们,而且它们完全不可维护。请,将复杂的任务放在脚本中,干净利落地写下评论,并使用 作为“单行”。

    编辑:经过一番思考,我意识到这个脚本可能尝试为grep -Cnum renum = C实施re = s(得到C上下文行,但它在内循环中得到循环索引错误(应该是i = j - C; i <= j + C)。

答案 1 :(得分:0)

谢谢你Kusalananda :)现在我的好奇心被释放了! 你是对这个循环的范围最初设计的是从j-c到j + c,但不知何故被修改,可能有人打算只找到一行,而不是几行。