【问题标题】:non-printable character not recognised as field separator不可打印的字符未被识别为字段分隔符
【发布时间】:2019-06-05 23:21:59
【问题描述】:

我有一个文件。它的字段分隔符是不可打印的字符\x1c(Python 中的chr(28))。在 VI 中,它看起来像 a^\b^\c,但使用 cat 我只看到 abc。没有看到字段分隔符^\。

我有一个简单的 awk 命令:

awk -F $’\x1c’ ‘{print NF}’ a

获取字段总数。它适用于 MacOS,但在 AIX 上却失败了。 AIX 似乎无法识别字段分隔符。所以输出是1,这意味着整行被认为是一个字段。 如何在 AIX 上执行此操作?任何想法都非常感谢。

【问题讨论】:

  • 创建test.py来准备数据
  • Python 代码:print('a'+chr(28)+'b'+chr(28)+'c'
  • 不是awk-特定的;使用 bash 而不是默认的 AIX-shell (ksh)。或者像这样使用printf:FldSep=$(printf '\034'); awk -F "$FldSep" ...
  • @LorinczyZsigmond 我必须使用 ksh。谢谢你的第二种方式有效。我不明白的一件事。你使用 \034 。是八进制数吗?我试过 FldSep=$(printf ‘\xc1’ );为什么不行?
  • 您是否尝试在 AIX 中使用 gawk(如果已安装)?

标签: shell unix awk aix


【解决方案1】:

我能够在运行 ksh 的 SOLARIS 上重现这一点。

sol bash $ printf '\034a\034b\034c' | cat -v
^\a^\b^\c$
sol bash $ printf '\034a\034b\034c' | awk -F$'\x1c' '{print NF}'
4
sol bash $ printf '\034a\034b\034c' | awk -F$'\034' '{print NF}'
4

sol ksh $ printf '\034a\034b\034c' | cat -v
^\a^\b^\c$
sol ksh $ printf '\034a\034b\034c' | awk -F$'\x1c' '{print NF}'
1
sol ksh $ printf '\034a\034b\034c' | awk -F$'\034' '{print NF}'
1

我无法确认这是 ksh 问题还是 awk 问题,因为其他情况都失败了。

sol ksh/bash $ printf '\034a\034b\034c' | awk 'BEGIN{FS="\034"}{print NF}'
1

以上所有案例都可以在任何 Linux 系统(默认运行 GNU awk)上成功运行,但似乎失败了。

以下技巧是一个完全不会失败的工作方法(直到它会失败):

sol ksh/bash $ printf '\034a\034b\034c' | awk 'BEGIN{FS=sprintf("%c",28)}{print NF}'
4

上述工作是因为我们让 awk 使用 sprintf 函数设置 FS,其中我们传递十进制数 28=x1c=034

【讨论】:

    【解决方案2】:

    $'\x1c' 是一个 bashizm, 可移植格式是 "$(printf '\034')"。

    (这个答案已经写成评论了。)

    【讨论】:

      【解决方案3】:

      当awk 有问题时,试试 Perl

      $ cat -vT tonyren.txt
      a^\b^\c^\d
      p^\q^\r^\s
      x^\y^\z
      
      $ perl -F"\x1c" -le ' { print scalar @F } ' tonyren.txt
      4
      4
      3
      
      $
      

      【讨论】:

      • 可以加hexdump file
      • 不,awk 没有sometimes break portability。 awk 有版本,就像 perl 一样,并且特定于版本的扩展只适用于指定的版本,仅此而已。如果您编写 POSIX awk 代码,那么它可以在大多数兼容 POSIX 的 awk 中工作,并且它的好处是每个 UNIX 安装都安装了 awk,而只有一些安装了 perl。
      • 对于这个问题,我认为它在 awk 中没有特定于版本的问题。也许我会改写它。正如 Marck Setchell 在他的 cmets 中提到的,Perl 是处理这种情况的方法。Perl 带有所有 *nix 风格,在企业版中,安装 CPAN 模块可能会被禁用。
      猜你喜欢
      • 2013-08-12
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      相关资源
      最近更新 更多