AWK 命令在 AIX 上未按预期工作

Posted

技术标签:

【中文标题】AWK 命令在 AIX 上未按预期工作【英文标题】:AWK command is not working as expected on AIX 【发布时间】:2021-05-06 14:07:58 【问题描述】:

我已经编写了下面的脚本来根据公共列名合并 2 个文件,它在 linux 机器上按预期运行,但是当我在 AIX 上执行相同的文件时,它会抛出错误

输入文件:

[user@XXXXX ~]$ cat file1.csv

TABLESPACE_name,PCT_FREE_01-02-21,PCT_FREE_02-02-21
SYSCATSPACE,50,50
TESTDTAI,50,50
USERSPACE1,98,98
TEMP32K,0,0
TEMP4K,0,0
TESTDTAL,49,49
TESTDTAT4K,50,50
TESTDTAT32K,0,0
TESTCTLI,8,8
TESTCTLL,0,0
TESTCTLT4K,2,2
TESTCTLT32K,25,25
SYSTOOLSPACE,94,94
SYSTOOLSTMPSPACE,0,0

[user@XXXXX ~]$ cat file2.csv
TABLESPACE_name,PCT_FREE_03-02-21
SYSCATSPACE,50
TESTDTAI,50
USERSPACE1,98
TEMP32K,0
TEMP4K,0
TESTDTAL,49
TESTDTAT4K,50
TESTDTAT32K,0
TESTCTLI,8
TESTCTLL,0
TESTCTLT4K,2
TESTCTLT32K,25
SYSTOOLSPACE,94
SYSTOOLSTMPSPACE,0`

命令:

awk -F"," 'NR==FNR a[$1] = $2; next for(i=1;i<=NF;i++) s=$s$(i)","print $s"," a[$1]' \
     file2.csv \
     file1.csv > tablespace_growth_`date +"%d-%m-%Y"`.csv

Linux 机器上的输出:

TABLESPACE_name,PCT_FREE_01-02-21,PCT_FREE_02-02-21,PCT_FREE_03-02-21
SYSCATSPACE,50,50,50
TESTDTAI,50,50,50
USERSPACE1,98,98,98
TEMP32K,0,0,0
TEMP4K,0,0,0
TESTDTAL,49,49,49
TESTDTAT4K,50,50,50
TESTDTAT32K,0,0,0
TESTCTLI,8,8,8
TESTCTLL,0,0,0
TESTCTLT4K,2,2,2
TESTCTLT32K,25,25,25
SYSTOOLSPACE,94,94,94
SYSTOOLSTMPSPACE,0,0,0

AIX 上的输出:

awk: 0602-562 Field $() is not correct.
 The input line number is 1. The file is file1.csv.
 The source line number is 1.

请帮助解决这个问题。

【问题讨论】:

print $s"," a[$1] 似乎有问题。您使用美元符号 ($) 来引用 awk 程序中的字段,后跟所需字段的编号。因此,$1 指第一个字段,$2 指第二个字段,依此类推。 使用s 代替$s——不同的awk 版本在语法错误方面并不完全兼容:一些变体比其他变体更宽容。 在 Linux 上,您可能正在运行 gawk,因此请添加 --lint 标志 (awk --lint -F...) 并阅读它给您的警告,特别是:awk: cmd. line:1: (FILENAME=file1.csv FNR=16) warning: attempt to field reference from non-numeric value SYSTOOLSTMPSPACE,0,0,0 等。 【参考方案1】:

print $s"," a[$1] 似乎有问题。您使用美元符号 ($) 来引用 awk 程序中的字段,后跟所需字段的编号。因此,$1 指的是第一个字段,$2 指的是第二个字段,依此类推。

它实际上是在内部生产

print $0 "," a[$1] 

因为您的变量 s 不是数字,所以计算结果为零 (0)

如果你仔细观察你的代码

awk -F","'NR==FNR a[$1] = $2;下一个 for(i=1;i 文件 2.csv file1.csv > tablespace_growth_date +"%d-%m-%Y".csv

for 循环结束后(您只是在每次迭代中覆盖相同的 s=$s$(i)","

Actual value of s=TABLESPACE_name,PCT_FREE_01-02-21,PCT_FREE_02-02-21PCT_FREE_02-02-21,

将评估为零 (0),因此打印当前记录,后跟数组值。

进一步展示:

$ cat testfile.txt 
1 2
3 4
5 6
7 8

$ awk ' string_val="non-numeric"; printf("$(%d) => %s\n", string_val,$(string_val))' testfile.txt
$(0) => 1 2
$(0) => 3 4
$(0) => 5 6
$(0) => 7 8

$ awk ' string_val="2"; printf("$(%d) => %s\n", string_val,$(string_val))' testfile.txt
$(2) => 2
$(2) => 4
$(2) => 6
$(2) => 8

以下内容可能对您有所帮助:

awk 'BEGINFS=OFS=","FNR==NRarr[$1]=$2;next$1 in arrprint $0,arr[$1]' file2.csv file1.csv

甚至

   awk 'BEGIN
           FS=OFS=","
         
         FNR==NR
           arr[$1]=$2;
           next
          
         
           printf("%s%s%s",$0,(($1 in arr)?OFS arr[$1]:""),RS)
         ' file2.csv file1.csv

输出:

$ awk 'BEGINFS=OFS=","FNR==NRarr[$1]=$2;next$1 in arrprint $0,arr[$1]' file2.csv file1.csv
TABLESPACE_name,PCT_FREE_01-02-21,PCT_FREE_02-02-21,PCT_FREE_03-02-21
SYSCATSPACE,50,50,50
TESTDTAI,50,50,50
USERSPACE1,98,98,98
TEMP32K,0,0,0
TEMP4K,0,0,0
TESTDTAL,49,49,49
TESTDTAT4K,50,50,50
TESTDTAT32K,0,0,0
TESTCTLI,8,8,8
TESTCTLL,0,0,0
TESTCTLT4K,2,2,2
TESTCTLT32K,25,25,25
SYSTOOLSPACE,94,94,94
SYSTOOLSTMPSPACE,0,0,0

输入:

$ cat file1.csv 
TABLESPACE_name,PCT_FREE_01-02-21,PCT_FREE_02-02-21
SYSCATSPACE,50,50
TESTDTAI,50,50
USERSPACE1,98,98
TEMP32K,0,0
TEMP4K,0,0
TESTDTAL,49,49
TESTDTAT4K,50,50
TESTDTAT32K,0,0
TESTCTLI,8,8
TESTCTLL,0,0
TESTCTLT4K,2,2
TESTCTLT32K,25,25
SYSTOOLSPACE,94,94
SYSTOOLSTMPSPACE,0,0

$ cat file2.csv 
TABLESPACE_name,PCT_FREE_03-02-21
SYSCATSPACE,50
TESTDTAI,50
USERSPACE1,98
TEMP32K,0
TEMP4K,0
TESTDTAL,49
TESTDTAT4K,50
TESTDTAT32K,0
TESTCTLI,8
TESTCTLL,0
TESTCTLT4K,2
TESTCTLT32K,25
SYSTOOLSPACE,94
SYSTOOLSTMPSPACE,0

【讨论】:

以上是关于AWK 命令在 AIX 上未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

子报表在 Matrix 上未按预期工作,具有向下钻取功能

Propel diff 命令未按预期工作

带有可选子命令的 argparse 未按预期工作

使用正则表达式查找命令未按预期工作

VB 选择案例未按预期工作

bulkDelete 方法未按预期工作