如何在AWK

时间:2018-06-15 18:29:40

标签: regex awk unicode grep

我有一个文件,我试图与表达式/ ^ [\ t] * r /匹配,我发现文件中的一行(第一行)令人沮丧地拒绝与awk或egrep匹配。有问题的线在视觉上(在编辑器中)显示确实以“r”开头;但是,当我使用od -ax转储文件时,我发现该文件实际上以以下内容开头:

0000000  o   ;   ?   r
          bbef    72bf

我该如何处理?理想情况下,我想在我的模式中为括号表达式添加一些内容,使得模式基本上用“以r开头”忽略空格,制表符和奇怪的非ascii垃圾。

3 个答案:

答案 0 :(得分:1)

您不能只使用gsub(/[^\x00-\x7F]/,"")过滤掉任何非ascii字符吗?例如:

$ awk 'BEGIN{printf "foo \xef\xbb\xbf bar\n"}' | cat -v
foo M-oM-;M-? bar

$ awk 'BEGIN{printf "foo \xef\xbb\xbf bar\n"}' | od -ax
0000000   f   o   o  sp   o   ;   ?  sp   b   a   r  nl
           6f66    206f    bbef    20bf    6162    0a72
0000014

$ awk 'BEGIN{printf "foo \xef\xbb\xbf bar\n"}' | awk '{gsub(/[^\x00-\x7F]/,"")}1' | cat -v
foo  bar

$ awk 'BEGIN{printf "foo \xef\xbb\xbf bar\n"}' | awk '{gsub(/[^\x00-\x7F]/,"")}1' | od -ax
0000000   f   o   o  sp  sp   b   a   r  nl
           6f66    206f    6220    7261    000a
0000011

[\x00-\x7F]是等同于[[:ascii:]]的awk,其他一些工具显然支持它。

答案 1 :(得分:0)

如评论中所述,那就是BOM。我在awk中使用它来删除它:

DynamoDB

答案 2 :(得分:0)

这是我为几乎任何您可以想象的 awk 版本编写的模块,它可以以 UTF8 的形式为您提供 any arbitrary byteany unicode character,无论您的语言环境设置如何,无论Windows/Mac/Unix,无论您是在字节模式还是 UC 感知模式下运行。它在 gawk、mawk134 和 mawk-2 beta 上进行了测试。我认为它在 nawk 中也应该可以正常工作。

function fast8(c0, base3){

    c0 = ((c0 ~ /[^0-9-]/) || (base3 ~ /[0-9]/ && base3 != 10)) \
          ? any2dec(c0, base3) : c0;

    return (c0 == -999) ? "" : (c0 < 2048) ? ( (c0 < 128) ?   \
                                                            \
        sprintf("%c", (c0 % 256) - 256 * (c0 > 0) ) :     \
        sprintf("%c%c",                                 \
           -64 +  int( c0 /     64),                  \
          -128 + (     c0           % 64)) ) : (c0 < 1114112) ? ( (c0 < 65536) ? \
        sprintf("%c%c%c",                           \
           -32 +  int( c0 /   4096)      ,         \
          -128 + (int( c0 /     64) % 64),        \
          -128 + (     c0           % 64)) :     \
        sprintf("%c%c%c%c",                     \
           -16 +  int( c0 / 262144)      ,     \
          -128 + (int( c0 /   4096) % 64),    \
          -128 + (int( c0 /     64) % 64),   \
          -128 + (     c0           % 64))) \
                                           \
      : sprintf("%c", (c0 % 256) - 256)   }

可选:自己插入一个函数 any2dec(),可以将非 base10 中的数字转换为 base10 中的十进制整数。如果您需要任何任意字节,请取其字节十进制整数值 [0,255]subtract 256

我承认这与 UTF8 的完整且符合标准的实现相距甚远,但对于日常使用而言,它非常接近。已经针对 0 到 1114111 之间的每个代码点在 gawk -e unicode 模式下针对 sprintf("%c") 进行了测试。

唯一的区别(有意为之)在于 U+D800 到 U+DFFF 的 UTF16 代理区域内。 GAWK 将空间视为一系列重复字节 0 到 255。此代码使用与任何其他 UC 代码点到 UTF8 映射相同的处理方式输出它们。

快速基准测试:(请记住,这是尝试将解释脚本与编译 C 二进制文件进行比较)循环 UC 的整个 110 万个代码点,20 次:

4.03s gawk -e unicode mode running fast8() native sprintf("%c")
___________________
14.74s mawk 1.9.9.6
14.79s mawk 1.3.4
26.99s gawk -b byte mode
34.92s gawk -e unicode mode running fast8()

*I hereby sharing this code in public domain (for any parts not currently covered under The Unicode Consortium), and rescind any past present or future claims of ownership or copyright to the intellectual property. Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the United States and other countries.*