【问题标题】:awk not showing right number of total field/column from my dataawk 没有从我的数据中显示正确的总字段/列数
【发布时间】:2020-03-30 08:11:03
【问题描述】:

我的示例数据如下所示,使用: cat -v sampel.txt(同时显示隐藏的特殊字符)

如果我将 sampel.txt 转储到 excel,使用分隔符 |,则总字段/列 是 75。 但是当我尝试计算总字段/列时,它只显示 12 个字段:

awk -F "|@~" '{print NF}' sampel.txt

12

我需要获取第 13 个字段的值 =53489958,但是当我输入以下内容时:

awk -F "|@~" '{print $13}' sampel.txt

什么都不显示。

仅供参考,我使用的是 IBM Aix Shell。

知道如何解决这个问题吗?是不是因为在字段 12th 和 13th 之间,有额外的特殊(隐藏)分隔符 ^@ ,意味着在我的样本数据中有多个分隔符(从字段 1 到 12,分隔符是 |@~,然后从字段 13 到是附加分隔符^@)。

那么我应该如何在 awk 过滤中输入正则表达式,以显示第 13 个字段的值 =53489958

我应该为正则表达式输入什么,这样我的 awk 中显示的总字段/列是 75 而不是 12 个字段/列?

这是我的原始数据,复制粘贴:

14027421900-23|@~14027421900|@~ 000000000000000000000000000000000005002.|@~ |@~0|@~ |@~ |@~ |@~ |@~ |@~ |@~ |@~53489958|@~ |@~ |@~0 |@~ |@~ |@~ |@~ |@~ |@~2018-06-01|@~305111010001|@~1000|@~7212|@~4|@~11|@~6|@~ |@~ |@~3|@~ 000000001847600.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00 | @~ 000000000000000.00|@~ 000000000000000.00|@~ 000000000000000.00|@~ |@~ |@~617598679|@~ |@~379311|@~1 |@~BL |@~2082-[2018416031915192 全部载入xls|@~P|@~
|@~2018-06-04|@~0 |@~2018-08-10|@~ |@~ |@~04062018|@~017318|@~017318|@~ |@~ |@~ |@~ |@~80079|@~022|@~ |@~0 |@~ |@~ 00000000000000000000000000000029157777。

【问题讨论】:

  • 作为图像的样本数据不会帮助丢失。将数据客栈剪切并粘贴到您的帖子中。
  • 欢迎来到 SO,感谢您为解决自己的问题所做的努力。请添加带有代码标签的文本格式示例,然后让我们知道。
  • @mas dani 您需要使用单个分隔符而不是多个分隔符,我会说,使用 sed 将这些分隔符更改为一个分隔符,例如 | 或您认为合适的分隔符,然后使用 awk .否则将awk -F<delimiter1> 传递给awk -F<delimiter2> 以获取/设置您想要的值。
  • @masdani - 它可能是也可能不是问题,但您文件中的那些 ^@s 可能是 NUL 字符。根据 POSIX,文本文件不能包含 NUL 字符(许多工具在内部使用 C 字符串来存储它们读取的输入,而 C 字符串是一组以 NUL 结尾的字符,因此其中一个字符不能为 NUL)并且 awk 是处理文本文件的工具。因此,如果在非文本文件上运行 awk 不能按您希望的那样工作,您不应该感到震惊。如果您拥有或可以获得 GNU awk,它将能够处理包含 NUL 的输入文件。否则,您必须使用 Excel 或类似工具将其删除。
  • @EdMorton 我的立场是正确的,我猜失去了一点联系

标签: bash awk


【解决方案1】:

感谢@EdMorton。是的,您是对的,似乎我在 AIX 中的 awk 版本无法解析 NULL 或 ^@ 正确,正如@Jotne 建议的那样,我尝试使用 -F'[|]@~' 但结果仍然相同,不能检测它。 瞧,再次感谢@tshiono,我用 Perl 尝试了你的食谱,它有效!太好了.. 现在我可以使用 Perl 的一个线性命令对原始数据中的所有数值字段求和,例如:

perl -lan -F'\|@~' -e '$sum += $F[13]; print "Sum is $sum" if eof' sampel.txt

此命令在我的 AIX shell 中告诉我源文件“sampel.txt”中的所有第 13 个字段求和,用特殊字符“\|@”分隔。

【讨论】:

    【解决方案2】:

    作为@EdMorton cmets,示例数据似乎包含NUL 字符。 一条线索是^@ 模式出现在cat -v 而 它们隐藏在剪切和粘贴的文本中。

    由于原来的 AWK 不能处理 NUL 字符,它可能已经停止了它的 遇到 NUL 字符时进行处理。这就是为什么NF 显示 只有 12 个。

    作为替代方案,使用可以处理二进制数据的perl 怎么样 包括 NUL 字符?我不是AIX 用户,但是 perl 应该预装在AIX 中。那么请尝试:

     perl -F'\|@~' -lane 'print $F[12]' sampel.txt
    
    • -F 选项指定字段分隔符(与awk 一样)。 您需要转义竖线,因为字段分隔符 是正则表达式模式,而竖线则被解释为元字符。
    • -lane options 告诉 perl 在处理换行符时表现得像 awk, 自动分割模式等。
    • 数组索引为“12”,因为perl 的数组索引从 0 开始,而不是 1。

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      你的字段分隔符是错误的。

      仅将| 作为分隔符,这是可以的-F'|' 但是当添加字符时,它会将| 视为或而不是按预期工作。试试-F'[|]@~'。它将给出以下分隔符:|@~

      -F'ab|zf' 将给出abzf 作为分隔符。

      【讨论】:

      • 这很有可能对 OPs 问题是正确的(如果没有一些具体的输入我无法判断),但通常将 | 作为 ERE(或 FS)的第一个字符) 实际上是每个 POSIX 未定义的行为,因此不同的 awks(和其他工具)会用它做不同的事情。例如,GNU awk 会将 FS 开头的 | 视为文字。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 2023-03-18
      • 2022-01-14
      • 2016-08-09
      • 2017-04-26
      相关资源
      最近更新 更多