【问题标题】:awk command or sed commandawk 命令或 sed 命令
【发布时间】:2018-05-15 14:59:42
【问题描述】:
000Bxxxxx111118064085vxas - header 
10000000001000000000053009-000000000053009-
10000000005000000000000000+000000000000000+
10000000030000000004025404-000000004025404-
10000000039000000000004930-000000000004930-
10000000088000005417665901-000005417665901-
90000060883328364801913 - trailer 

在上面的文件中,我们有header和trailers,以1开头的记录是详细记录 在详细记录中,想要对从位置 28 到 44 的值求和,包括使用 awk/sed 命令的符号

【问题讨论】:

  • 您能否阐明您的预期输出,并向我们展示您迄今为止所做的尝试?
  • 欢迎来到 Stack Overflow!抱歉,这不是 StackOverflow 的工作方式。 “我想做 X,请给我提示和/或示例代码”形式的问题被认为是题外话。请访问help center并阅读How to Ask,尤其是阅读Why is “Can someone help me?” not an actual question?
  • wan 总结特定输出文件中的字段
  • 或输出文件
  • 另外,为什么只有 awk/sed?

标签: awk sed


【解决方案1】:

这里是 sed,在 bc 的帮助下进行算术运算:

sed -rn '
    /header|trailer/! {
        s/[[:digit:]]*[+-]([[:digit:]]+)([+-])$/\2\1/
        H
    }
    $ {
        x
        s/\n//gp
    }
' file | bc

我假设+/- 符号跟在数字后面。

【讨论】:

    【解决方案2】:

    使用awk我们可以利用substr解决这个问题:

    substr(s, m[, n ]): 返回从位置m 开始的s 的最多n 字符子字符串,从1 开始编号。如果省略n,或者如果n 指定的字符数超过字符串中剩余的字符数,则长度子字符串的长度应受字符串s的长度限制。

    这允许我们获取代表数字的字符串。在这里,我假设数字前后的符号相同,因此数字的符号:

    $ echo "10000000001000000000053009-000000000053009-" \
      | awk '{print length($0); print substr($0,27,43-27)}'
    43
    -000000000053009
    

    由于awk 隐式地将字符串转换为数字,如果您对它们进行数字运算,我们可以编写以下awk-代码来实现请求:

    $ awk '/header|trailer/{next}
           {s+=substr($0,27,43-27)}
           END{print s}' file.dat
    -5421749244
    

    或单行:

    $ awk '/header|trailer/{next}{s+=substr($0,27,43-27)} END{print s}' file.dat
    -5421749244
    

    以上示例仅适用于 OP 提供的示例文件。但是,如果您的文件包含多个带有 headertrailer 的块,并且您只想使用这些块内的文本(排除块外的所有内容),那么您应该以不同的方式处理它:

    $ awk '/header/{s=0;c=1;next}
           /trailer/{S+=s;c=0;next}
           c{s+=substr($0,27,43-27)}
           END{print S}' file.dat
    

    在这里我们执行以下操作:

    • 如果找到带有header 的行,则将块总和s 重置为ZERO 并设置c=1 表示我们考虑下一行
    • 如果找到带有trailer 的行,则将块总和s 添加到总和S 并设置c=0 表示忽略这些行。
    • 如果c/=0 计算块总和s
    • END,打印总和S

    【讨论】:

    • 谢谢,但我显示的数据在一个文件中,并且对这个 awk 来说是新的,所以需要帮助来替换其中的文件。
    • 用文件名替换<FILE>,这应该可以。请注意,这仅假定单个块 header,trailer
    • cat file1.dat | '/header|trailer/{next}{s+=substr($0,27,44-28)}END{print s}' file1.dat.sumbal
    • 对于上面提到的示例文件,但是当我使用由 609655 条记录组成的真实文件时,它显示为零....
    • 当我们使用这些 awk 命令时是否有任何记录计数限制?
    猜你喜欢
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    相关资源
    最近更新 更多