AWK Mac OSX如何在同一行打印数组键和数组值

Posted

技术标签:

【中文标题】AWK Mac OSX如何在同一行打印数组键和数组值【英文标题】:AWK Mac OSX how to print array key and array value on same line 【发布时间】:2017-05-06 06:46:28 【问题描述】:

我意识到 AWK 程序在 Mac OSX 和 Linux 发行版上有所不同,但即使使用自制软件中的gawk,我也无法获得相同的结果。我希望了解我的 AWK 脚本需要调整哪些内容才能在我的 Mac 上运行,以便在同一行上打印数组键及其值。

这是我的 awk 文件:

BEGIN  FS="," 
NR > 1 
    dupes[$3]++;


END 
    OFS=" ";
    for (key in dupes) 
        if (dupes[key] > 1) 
            print key, "occured", dupes[key], "times";

        
    

这是一个 test.csv 文件

test,something,target_column3
aaa,123,hi
sss,222,hello
ddd,333,hey
fff,444,hi
ggg,555,hi
jjj,888,goodbye
uuu,666,byebye
lll,777,hey

我希望输出在 Ubuntu 上显示为 GNU Awk 4.0.1:

hey occured 2 times
hi occured 3 times

但在我的 Mac 上,它输出 gawk 版本 GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5, GNU MP 6.1.2):

 occured 2 times
 occured 3 times

无论出于何种原因,当与另一个变量 dupes[key] 并排时,它不会打印我的 for 循环的 key。但是,当它是唯一在线时,它将print key

更新:根据@jas 评论,我检查了行尾,无论出于何种原因,我的 csv 文件都有CRLF。此外,添加如下所示的打印值会显示一些奇怪的输出。我希望所有的长度都少一个字符,而不是我得到:

 ...
    NR > 1 
        print length($3);
        dupes[$3]++;
    
 ...


3
6
4
3
3
8
7
4
occured 2 times
occured 3 times

为什么 Mac OSX AWK(或 GAWK)不能在同一行打印数组键和数组值?

【问题讨论】:

无法重现。你的终端可能有问题?尝试将输出重定向到文件并使用文本编辑器查看它。 “无法复制”是指在 /usr/bin/awk 和 gawk 4.1.4 (macports) 上按预期工作 当您的文件中有错误的行尾时,可能会发生这种情况。就像一个控制字符卡在 $3 的末尾,它在继续写入字符之前将光标移动到行首。 尝试打印length($3)。是你所期望的吗? 我认为你只需要在你的文件上运行一个 dos2unix 实用程序。 【参考方案1】:

由于您的文件具有 DOS 样式的 CRLF 行尾,并且 Mac 上的 awk 仅将 LF 识别为行尾,因此 CR 将作为附加字符包含在最后一个字段的末尾(本例中为 $3)。

然后,当打印 $3 时,CR 充当控制字符,在继续输出之前移动到行首,覆盖那里的内容,使其看起来好像从未打印过。

因此,正如您所验证的,解决方案是简单地在您的文件上运行 dos2unix 实用程序,使其与您的环境兼容。

【讨论】:

这肯定是最常见的问题来源,希望有办法告诉遇到问题的每个人先检查一下!【参考方案2】:

这是一种无需修改原始输入文件的替代解决方案:

简单添加

 RS = sprintf("%c%c%c%c%c", 10, 124, 13, 10, 63) 

BEGIN 部分。

这些 ASCII 值等价于 RS="\n|\r\n?"RS="\12\174\15\12\77" , 如果你喜欢八进制代码

这样您就可以拥有任何混合的输入文件集,无论它们来自

 1. PC/Windows/DOS world,
 2. classic pre-MacOS X world,
 3. Unix/Linux/modern-Mac world, or even
 4. IBM mainframe world with EBCDIC encodings

根本无需修改任何原始输入文件,也无需按来源系统分离输入或您的代码。

(此解决方案已被验证可在 mawk-1mawk-2nawkgawk 及其任何调用标志上工作,模式 -c/-P 除外。奇怪的是,适用于 gawk -t

【讨论】:

以上是关于AWK Mac OSX如何在同一行打印数组键和数组值的主要内容,如果未能解决你的问题,请参考以下文章

c语言输入的值如何在同一行打印输出

在Ruby中的同一行中打印不同大小数组的数组元素

(C/C++) 在同一行初始化并返回数组

如何从嵌套 Json 数组角度 2 打印和分离键和值并将其添加到选择框中

在 awk 循环中访问 bash 数组

如何在同一行打印2个项目[重复]