如何在AWK脚本中正确检查CSV文件各列的数据类型?
解决AWK实现列级数据类型判断的问题
背景
在Python的Pandas库中,可通过dtypes查看数据框各列的数据类型。但AWK采用逐行处理模式,无法直接实现列级数据类型检查,需要遍历所有行的列值来推断类型。
用户现有问题
用户编写的AWK脚本仅对整行做类型判断,且正则表达式存在错误,导致输出不符合预期:
原AWK脚本
BEGIN{ FS=","; } function whatisit(x){ if(x~"^[0-9][0-9]*$") {return "int"}; if(x~"^[a-zA-Z][a-z[A-Z]*$") {return "char"}; return "symbol"} {print $0"--->"whatisit($0)}
原执行输出
:~/AWK$ awk -f bin.awk sample.csv c1,c2,c3,c4,c5--->symbol 1,a,aad,24,10.3--->symbol 2,b,sdsf,90,84.2--->symbol 3,c,dfd,28,84.2--->symbol 4,d,dhj,29,10.4--->symbol 5,e,kae,19,30.4--->symbol 6,f,IEF,93,83.1--->symbol
期望输出
:~/AWK$ awk -f bin.awk sample.csv c1 --> int c2 --> char c3 --> char c4 --> int c5 --> float
示例CSV文件内容
c1,c2,c3,c4,c5 1,a,aad,24,10.3 2,b,sdsf,90,84.2 3,c,dfd,28,84.2 4,d,dhj,29,10.4 5,e,kae,19,30.4 6,f,IEF,93,83.1
解决方案
要实现列级类型推断,需要遍历所有行的每一列,根据列内所有值的类型确定最终类型。以下是修正后的AWK脚本:
BEGIN { FS = "," } # 保存表头并初始化列类型为int NR == 1 { for (i = 1; i <= NF; i++) { col_names[i] = $i col_types[i] = "int" } next } # 遍历每行的列值,更新列类型 { for (i = 1; i <= NF; i++) { val = $i # 判断是否为浮点数,若当前是int则升级为float if (val ~ /^[0-9]+\.[0-9]+$/) { if (col_types[i] == "int") { col_types[i] = "float" } } # 若为整数且当前类型不是float则保持int else if (val ~ /^[0-9]+$/ && col_types[i] != "float") { continue } # 否则标记为char类型 else { col_types[i] = "char" } } } # 输出最终的列名与类型 END { for (i = 1; i <= length(col_names); i++) { printf " %s --> %s\n", col_names[i], col_types[i] } }
原脚本问题说明
- 处理对象错误:原脚本将整行
$0传入判断函数,而非逐列处理$i; - 正则表达式错误:字符类型的正则
^[a-zA-Z][a-z[A-Z]*$存在语法错误,且未覆盖所有字符串场景; - 缺少float类型判断:原逻辑未考虑带小数的数值类型;
- 未收集列的全局类型:仅判断单行的整行内容,无法反映列的整体类型。
内容的提问来源于stack exchange,提问作者senthil
相关产品推荐
相关产品推荐

